185 lines
6.0 KiB
Markdown
185 lines
6.0 KiB
Markdown
# 绑定方向及数据更新
|
||
|
||
Path 绑定属性名称,Source 绑定数据源,绑定属性必须是依赖属性
|
||
|
||
UpdateSourceTrigger 更新源触发器
|
||
|
||
PropertyChanged LostFocus Explicit Default
|
||
|
||
可以用控件.SetBinding(控件静态属性,new Binding("Path")){Source=xxx}
|
||
如果绑定的集合类的属性仍然是集合,可以用'/',将子集集合中的元素当作Path
|
||
|
||
绑定属性可以为控件静态属性 Path=Text.Length;
|
||
|
||
Source本身就代表数据,如字符串的时候,Path可以省略只留下Binding或Binding Path=.或Binding .;
|
||
|
||
Binding的源类型(Source)
|
||
|
||
- clr类型对象
|
||
- clr集合对象:ItemsSource
|
||
- ADO.Net数据对象 DataTable DataView,DataTable.DefaultView;
|
||
ListView派生与ListBox,GridView继承ViewBase,ListView.View是ViewBase类型。目前ListView.View只能用GridView。
|
||
- XmlDataProvider XML数据,TreeView Menu,XmlDataProvider.Source=new Urine(@"路径"),XPath=(要提取的节点,如/StudentList/Student);可以作为资源把xml内容放在<x:XData>标签内;
|
||
- 依赖对象 Dependency Object 可以作为源和目标,依赖对象的依赖属性作为Path
|
||
- 容器DataContext(上下文数据源,依赖属性),无法明确是从哪个源的属性获取数据时,它上层的DataContext会沿着UI树往下传递,直到找到源中有对应Path的属性后,将该DataContext作为自己的源
|
||
DataContext使用场景:
|
||
a. 当UI上的多个控件使用Binding关注同一个对象时
|
||
b. 当Source对象不能被直接访问时,如Private,B窗口访问A窗口的控件时,将A窗口的控件作为数据源时,可以使用把控件作为窗口A的DataContext(public),暴露数据。
|
||
- ELementName=控件名
|
||
- RelativeSource属性相对地指定Source
|
||
RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}
|
||
RelativeSourceMode枚举:
|
||
FindAncestor查找父级,TemplatedParent,PreviousData;
|
||
AncestorType父级类型,AncestorLevel层级便宜量,上一级为1,三个美剧
|
||
- ObjectDataProvider
|
||
|
||
```csharp
|
||
ObjectDataProvider odp=new ObjectDataProvider()
|
||
odp.ObjectInstance=new Class();
|
||
odp.MethodName="方法名"
|
||
odp.MethodParameters.Add("参数值")
|
||
Binding bindingToArg1=new Binding("MethodParameters[0]")
|
||
{
|
||
Source=odp,
|
||
BindsDirectlyToSource=true,
|
||
UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged
|
||
}
|
||
Binding bindingToResult=new Binding("."){Source=odp}
|
||
//关联
|
||
控件.SetBinding(控件静态属性,bindingToArg1)
|
||
控件.SetBinding(控件静态属性,bindingToResult)
|
||
```
|
||
|
||
- Linq检索得到的数据对象
|
||
|
||
```csharp
|
||
XDocument xdoc=XDocument.Load();
|
||
from element in xdoc.Descendants("节点名称")
|
||
where element.Attribute("特性").Value....
|
||
select new Class()//转实例
|
||
{
|
||
|
||
}
|
||
```
|
||
|
||
# 数据校验
|
||
|
||
```csharp
|
||
public class RangeValidationRule:ValidationRule
|
||
{
|
||
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
|
||
{
|
||
double d=0;
|
||
if (double.TryParse(value.ToString(),out d))
|
||
{
|
||
if(d>=0&&d<=100>)
|
||
{
|
||
return new ValidationResult(true,null);
|
||
}
|
||
}
|
||
return new ValidationResult(false,"Validation Failed");
|
||
}
|
||
}
|
||
public Window(){
|
||
InitializeComponent();
|
||
Binding binding=new Binding("Value"){Source=this.slider}
|
||
binding.UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged
|
||
RangeValidationRUle rvr=new RangeValidationRUle()
|
||
rvr.ValidatesOnTargetUpdated=true//校验源数据
|
||
binding.ValudationRules.Add(rvr)
|
||
binding.NotifyOnValidationError=true;//校验错误,发出通知
|
||
this.textBox.SetBinding(TextBox.TextProperty,binding)
|
||
}
|
||
void ValidationError(object sender,RoutedEventArgs e){
|
||
if(Validation.GetErrors(this.textBox).Count>0)
|
||
{
|
||
this.textBox.ToolTip=Validation.GetErrors(this.textBox)[0].ErrorContent.ToString()
|
||
}
|
||
}
|
||
```
|
||
|
||
数据转换
|
||
|
||
```csharp
|
||
public class CategoryToSourceConverter:IValueConverter
|
||
{
|
||
//源=>目标(控件)
|
||
public object Converter(object value,Type targetType,object parameter,CultureInfo culture)
|
||
{
|
||
Category c=(Category)value;
|
||
switch(c)
|
||
{
|
||
case Category.Bomber:
|
||
return @"Icon/Bomber.png";
|
||
case Category.Fighter:
|
||
return @"Icon/Fighter.png";
|
||
Default:
|
||
return null;
|
||
}
|
||
}
|
||
public object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
}
|
||
public class StateToNullableBoolConverter:IValueConverter
|
||
{
|
||
//源=>目标(控件)
|
||
public object Converter(object value,Type targetType,object parameter,CultureInfo culture)
|
||
{
|
||
State s=(State)value;
|
||
switch(s)
|
||
{
|
||
case State.Locked:
|
||
return false;
|
||
case State.Available:
|
||
return true;
|
||
default:
|
||
return null;
|
||
}
|
||
}
|
||
|
||
public object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture)
|
||
{
|
||
bool? nb=(bool?)value
|
||
switch(nb)
|
||
{
|
||
case false:
|
||
return State.Locked;
|
||
case true:
|
||
return State.Available;
|
||
default:
|
||
return State.Unknown;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
```xaml
|
||
<Window.Resources>
|
||
<local:CategoryToSourceConverter x:Key="cts"/>
|
||
<local:StateToNullableConverter x:Key="stnb"/>
|
||
</Window.Resources>
|
||
<ListBox.ItemTemplate>
|
||
<DataTemplate>
|
||
<StackPanel Orientation="Horizontal">
|
||
<Image Source="{Binding Path=Category,Converter={StaticResource cts}}">//绑定
|
||
<CheckBox IsThreeState="True" IsCheck="{Binding Path=State,Converter={StaticResource stnb}}">
|
||
</StackPanel>
|
||
</DataTemplate>
|
||
</ListBox.ItemTemplate>
|
||
```
|
||
|
||
MultBinding使用场景一:需要通过多个对象属性综合进行判断时;
|
||
Binding b1=new Binding("Text){Source=this.textBox1}
|
||
Binding b1=new Binding("Text){Source=this.textBox2}
|
||
MulitBinding mb=new MulitBinding(){Mode=Binding.OneWay}
|
||
mb.Bindings.Add(b1)//注意绑定顺序
|
||
mb.Bindings.Add(b2)
|
||
mb.Converter=LoginMultiBindingConverter()
|
||
this.btn.SetBinding(Button.IsEnabledProperty,mb)
|
||
public class LogoMultiBindingConverter: IMultiValueConverter
|
||
{
|
||
|
||
}
|