Files
06-Note/WPF/Binding.md
sherlockforrest bf2ed2e31f 更新
2023-06-20 09:22:53 +08:00

6.0 KiB
Raw Permalink Blame History

绑定方向及数据更新

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
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检索得到的数据对象
XDocument xdoc=XDocument.Load();
  from element in xdoc.Descendants("节点名称")
  where  element.Attribute("特性").Value....
  select new Class()//转实例
  {

  }

数据校验

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()
  }
}

数据转换

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;
    }
  } 
}
<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 {

}