Binding 是前台UI(显示层)和后台代码(数据层)的桥梁。理论上当后台的数据变动时,显示的数据或样式应该随之而变。这些是动态的。

对于Binding的设置可以在前台Xaml,也可以在后台Code里面定义,但是既然Xaml可以做很多事情,那么所有对UI的操作我们都可以交给它。

其实,WPF的本身是一种数据驱动UI的设计模式,使用了MVVM(Model-View-ViewModel)的模式。

以下是绑定的基本思路:

目标(依赖对象(依赖属性))  <=====Binding =====> 源(CLR 对象(属性))

实验1:

设计一个圆形的球,包括红球和篮球,有编号。初始状态为灰色,当选中时,红球颜色显示为红,篮球颜色显示为蓝。再次选中时,颜色返回为初始状态(灰色)

另外,当球被选中时,可以处理一下数据,如读取编号。

思路:

1.首先设计一个Ball 类 包含了IsSelected, Type, Index 属性,并继承了INotifyPropertyChanged接口,当IsSelected属性变更的时候,产生了PropertyChanged的Event。

2.创建了一个BallControl的 User Control (WPF).

3.bindingBall类到BallControl上。对binding做一些设定,从而实现实验1的需求。

实现:

1. 新建Ball类. 实现INotifyPropertyChanged 接口,当属性IsSelected值变化的时候,调用PropertyChanged event

    public class Ball : INotifyPropertyChanged
{
/// <summary>
/// Fired whenever a property changes. Required for
/// INotifyPropertyChanged interface.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged; private bool selected; private BallType type; private int index; private Point size; public Ball()
:this(false, BallType.gray, , new Point(,))
{
} public Ball(bool ballIsSelected, BallType ballType, int ballIndex, Point ballSize)
{
this.selected = ballIsSelected;
this.type = ballType;
this.index = ballIndex;
this.size = ballSize;
} public bool IsSelected
{
get
{
return this.selected;
} set
{
if (value != this.selected)
{
this.selected = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"
));
}

}
}
} public BallType Type
{
get
{
return this.type;
}
} public int Index
{
get
{
return this.index;
}
}
} public enum BallType
{
gray, Red, Blue,
}

2. 新建一个User Control (WPF), 名为BallControl,依次放入Grid, Border, Ellipse, TextBlock 控件. 完成 UI 布局。

在后台为鼠标点击动作添加一个Event,当Ball控件被点击选择的时候,会做一些需要的处理。

<UserControl x:Name="myBallControl"
x:Class="BallSelection.BallControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BallSelection"
mc:Ignorable="d"
Height="100"
Width="100">
<Grid Height="100"
Width="100"
VerticalAlignment="Top"
MouseDown="UIElement_OnMouseDown"
>
<Border BorderBrush="Black"
BorderThickness="1"
HorizontalAlignment="Left"
Width="100"
Height="100"
RenderTransformOrigin="0.481,0.183">
<Ellipse x:Name="circle"
Stroke="Black"
Margin="6,6,6,6">
</Ellipse>
</Border>
<TextBlock x:Name="tbIndex"
Text="0"
FontSize="58"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</UserControl>
    /// <summary>
/// Interaction logic for BallControl.xaml
/// </summary>
public partial class BallControl : UserControl
{
public event EventHandler<EventArgs> SelectionChanged; public BallControl()
{
InitializeComponent();
} private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (this.SelectionChanged != null)
{
this.SelectionChanged(this
, EventArgs.Empty);
}
}

}

4. 设计MainWindow的UI,依次放入Grid,WrapStack,和BallControl。

<Window x:Class="BallSelection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BallSelection"
Title="MainWindow"
Height=""
Width="">
<Grid>
<Grid HorizontalAlignment="Left"
Height=""
Margin="51,38,0,0"
VerticalAlignment="Top"
Width="">
<WrapPanel x:Name="wpBalls"
HorizontalAlignment="Left"
Height=""
VerticalAlignment="Top"
Width="">
<local:BallControl x:Name="redBallControl" />
<local:BallControl x:Name="blueBallControl" />

</WrapPanel>
</Grid>
</Grid>
</Window>

5. 进行Binding, 有两种方法:一种是在后台Code里面进行binding, 另外一种是在前台Xaml里面进行binding。

方法一:在后台Code里面进行binding

 public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent(); this.InitializeBalls();
} private void InitializeBalls()
{
Ball redBall = new Ball(false, BallType.Red, , new Point(,)); Binding bindingIndex = new Binding()
{
Source = redBall,
Path = new PropertyPath("Index")
}; // this is equal to: this.blueBallControl.tbIndex.SetBinding(TextBlock.TextProperty, bindingIndex);
BindingOperations.SetBinding(this.redBallControl.tbIndex, TextBlock.TextProperty, bindingIndex); Binding bindingSelect = new Binding()
{
Source = redBall,
Path = new PropertyPath("IsSelected"),
Converter = new BooleanToColor(),
}; BindingOperations.SetBinding(this.redBallControl.circle, Ellipse.FillProperty, bindingSelect); // Handle selection changed event.
this.redBallControl.SelectionChanged += ((s, e) =>
{
redBall.IsSelected = !redBall.IsSelected;
MessageBox.Show(string.Format("BallControl Index {0} is selected.\t\n. Ball Type:{1}, Index:{2}, IsSelected:{3}.", this.redBallControl.tbIndex.Text, redBall.Type.ToString(), redBall.Index, redBall.IsSelected));
});
} }

这里在binding的过程中,当ball control被选中的时候, 颜色会自动进行转换,所以需要一个Converter。

    public class BooleanToColor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(Brush))
throw new InvalidOperationException("The target must be a Brush"); if (value == null)
return Brushes.Gray; return (bool)value ? Brushes.Red : Brushes.Gray;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}

方法二:在前台Xaml里面进行binding

(待续)

(WPF) 再议binding:点击User Control时,User Control变换颜色或做其他的处理。的更多相关文章

  1. Easyui之datagrid实现点击单元格修改单元格背景颜色

    前段时间有个需求中有点击datagrid的单元格实现某种事件,调用datagrid的onclickCell这个方法很容易实现,但是体验不好啊,完全不知道自己刚才点击的是哪个单元格,然后就尝试单击单元格 ...

  2. 【转】WPF中的Binding技巧(二)

    WPF中的Binding技巧(二)     接上篇, 我们来看一看Elementname,Source,RelativeSource 三种绑定的方式 1.ElementName顾名思义就是根据Ui元素 ...

  3. 再议 js 数字格式之正则表达式

    原文:再议 js 数字格式之正则表达式 前面我们提到到了js的数字格式<浅谈 js 数字格式类型>,之前的<js 正则练习之语法高亮>里也提到了优化数字匹配的正则.不过最近落叶 ...

  4. Python学习之再议row_input

    再议raw_input birth = raw_input('birth: ') if birth < 2000: print '00前' else: print '00后' 运行结果: bir ...

  5. 再议Java中的static关键字

    再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...

  6. VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法。

    原文:VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net ...

  7. 再议perl写多线程端口扫描器

    再议perl写多线程端口扫描器 http://blog.csdn.net/sx1989827/article/details/4642179 perl写端口多线程扫描器 http://blog.csd ...

  8. Control.Invoke和Control.BeginInvoke

    问题的引入 下面有个简单的demo,大家一看代码就知道效果如何示例.我新建一个winform的程序,然后写入了如下代码: using System; using System.Windows.Form ...

  9. 微信6.7.4 ios12 软键盘收回时页面不回弹,导致光标位置错乱,再次点击输入框区域时无法focus

    https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800 https://blog.c ...

随机推荐

  1. Spring MVC 使用拦截器优雅地实现权限验证功能

    在上一篇 SpringAOP 实现功能权限校验功能 中虽然用AOP通过抛异常,请求转发等勉强地实现了权限验证功能,但感觉不是那么完美,应该用拦截器来实现才是最佳的,因为拦截器就是用来拦截请求的,在请求 ...

  2. leetcode 143. Reorder List ----- java

    Given a singly linked list L: L0→L1→-→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do thi ...

  3. spark 分析sql内容再插入到sql表中

    package cn.spark.study.core.mycode_dataFrame; import java.sql.DriverManager;import java.util.ArrayLi ...

  4. Android——模拟文件拷贝

    模拟文件拷贝:要求:要用progressDialog和子线程来模拟显示拷贝进度:进度完成后在主界面提示拷贝完成,分别使用普通方式和消息机制编写. layout文件: <?xml version= ...

  5. MySql的FIND_IN_SET()查询函数的使用

    表 table的结构如下: id title 1 12,21 2 21,32 3 45,21,78 4 221,45,74 5 34,421,121 6 52,21,321 现在用sql语句查出来字段 ...

  6. 【NOIP2013】【P1441】花匠

    又一次看错题…… 原题: 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比 ...

  7. CENTOS 下编译HTK

    在centenos下编译HTK碰到缺少libX11库,需要安装 libX11-dev libXext-dev libXtst-dev

  8. Is it possible to configure PostgreSQL to automatically close idle connections?

    1.use pgbouncer As new connections/transactions/statements arrive, the pool will increase in size up ...

  9. combobox select .change onSelect事件触发

    我现在要完成的功能是:有两个下拉框,当地一个下拉框选择了第一个选项时,第二个下拉框不可用,否则就可用. 用了jQuery easyUI提供的onSelect方法.如下:js文件:$('#select1 ...

  10. Code First 约定

    Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code Fi ...