Files
06-Note/WPF/Binding.md

185 lines
6.0 KiB
Markdown
Raw Permalink Normal View History

2023-06-20 09:22:53 +08:00
# 绑定方向及数据更新
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 DataViewDataTable.DefaultView;
ListView派生与ListBoxGridView继承ViewBaseListView.View是ViewBase类型。目前ListView.View只能用GridView。
- XmlDataProvider XML数据TreeView MenuXmlDataProvider.Source=new Urine(@"路径")XPath=(要提取的节点,如/StudentList/Student);可以作为资源把xml内容放在<x:XData>标签内;
- 依赖对象 Dependency Object 可以作为源和目标依赖对象的依赖属性作为Path
- 容器DataContext上下文数据源,依赖属性无法明确是从哪个源的属性获取数据时它上层的DataContext会沿着UI树往下传递直到找到源中有对应Path的属性后将该DataContext作为自己的源
DataContext使用场景
a. 当UI上的多个控件使用Binding关注同一个对象时
b. 当Source对象不能被直接访问时如PrivateB窗口访问A窗口的控件时将A窗口的控件作为数据源时可以使用把控件作为窗口A的DataContextpublic暴露数据。
- 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>
<localCategoryToSourceConverter x:Key="cts"/>
<localStateToNullableConverter 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
{
}