WPF中的几种绑定情况

前言

在WPF中,前台控件应该很好的与数据进行绑定关联,不在像WinForm那样在后台拿着控件去操作,基于数据驱动的原则,写好绑定可以方便后台代码逻辑,并且代码看着更加简结。

1、XmlDocument与控件绑定

使用XPath选择需要显露的数据

前台代码

<ListView x:Name="listViewStudents" Height="130" Margin="5">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" Width="80" DisplayMemberBinding="{Binding XPath=@Id}"/>
                    <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding XPath=Name}"/>
                    <GridViewColumn Header="Age" Width="80" DisplayMemberBinding="{Binding XPath=Age}"/>
                </GridView>
            </ListView.View>
        </ListView>

后台代码

XmlDocument doc = new XmlDocument();
            doc.Load("XMLFile1.xml");

            XmlDataProvider xdp = new XmlDataProvider();
            xdp.Document = doc;

            //使用XPath选择需要显露的数据

            xdp.XPath = @"/StudentList/Student";
            this.listViewStudents.DataContext = xdp;
            this.listViewStudents.SetBinding(ListView.ItemsSourceProperty, new Binding());

数据文件

<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
  <Student Id="1">
    <Name>Tim</Name>
    <Age>20</Age>
  </Student>
  <Student Id="2">
    <Name>Tom</Name>
    <Age>25</Age>
  </Student>
  <Student Id="3">
    <Name>Vina</Name>
    <Age>28</Age>
  </Student>
  <Student Id="4">
    <Name>Emily</Name>
    <Age>33</Age>
  </Student>
</StudentList>

2、XmlDataProvider绑定

数据代码

<Window.Resources>
        <XmlDataProvider x:Key="xdp" XPath="FileSystem/Folder">
            <x:XData>
                <FileSystem xmlns="">
                    <Folder Name="Programming">
                        <Folder Name="Windows">
                            <Folder Name="WPF"/>
                            <Folder Name="MFC"/>
                            <Folder Name="Delphi"/>
                        </Folder>
                    </Folder>
                    <Folder Name="Tools">
                        <Folder Name="Development"/>
                        <Folder Name="Designment"/>
                        <Folder Name="Players"/>
                    </Folder>
                </FileSystem>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>

控件关联

<TreeView ItemsSource="{Binding Source={StaticResource xdp}}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding XPath=Folder}">
                    <TextBlock Text="{Binding XPath=@Name}"/>
                    
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

3、数据列表直接关联

前台

<ListView x:Name="listViewStudents" Height="143" Margin="5">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" Width="60" DisplayMemberBinding="{Binding ID}"/>
                    <GridViewColumn Header="Name" Width="100" DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn Header="Age" Width="80" DisplayMemberBinding="{Binding Age}"/>
                </GridView>
            </ListView.View>
        </ListView>

后台

this.listViewStudents.ItemsSource = from stu in stuList where stu.Name.StartsWith("T") select stu;


List<Student> stuList = new List<Student>()
        {
            new Student(){ID=0,Name="Tim",Age=29},
            new Student(){ID=1,Name="Tom",Age=28},
            new Student(){ID=2,Name="Kyle",Age=27},
            new Student(){ID=3,Name="Tony",Age=26},
            new Student(){ID=4,Name="Vina",Age=25},
            new Student(){ID=5,Name="Mike",Age=24},
        };

数据结构

 class Student
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }
    }

4、ObjectDataProvider使用

前台

<StackPanel>
        <TextBox x:Name="tb_arg1" Margin="5"/>
        <TextBox x:Name="tb_arg2" Margin="5"/>
        <TextBox x:Name="tbResult" Margin="5"/>
        <Button x:Name="text" Content="11" Click="text_Click"></Button>
    </StackPanel>

后台

private void SetBinding()
        {
            //创建并配置ObjectDataProvider对象
            ObjectDataProvider odp = new ObjectDataProvider();
            odp.ObjectInstance = new Calculator();
            odp.MethodName = "Add";
            odp.MethodParameters.Add("0");
            odp.MethodParameters.Add("0");

            //以ObjectDataProvider对象为Source创建Binding
            Binding bidingToArg1 = new Binding("MethodParameters[0]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };

            Binding bidingToArg2 = new Binding("MethodParameters[1]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };

            Binding bindingToResult = new Binding(".") { Source = odp };

            //将Binding关联到UI元素上
            this.tb_arg1.SetBinding(TextBox.TextProperty, bidingToArg1);
            this.tb_arg2.SetBinding(TextBox.TextProperty, bidingToArg2);
            this.tbResult.SetBinding(TextBox.TextProperty, bindingToResult);
        }

计算逻辑

 class Calculator
    {
        public string Add(string arg1,string arg2)
        {
            double x = 0;
            double y = 0;
            double z = 0;
            if (double.TryParse(arg1,out x)&&double.TryParse(arg2,out y))
            {
                z = x + y;
                return z.ToString();
            }
            return "Input Error!";
        }
    }

5、两个控件关联

前台

<StackPanel>
        <TextBox x:Name="textBox1" Margin="10"/>
        <Slider x:Name="slider1" Minimum="-10" Maximum="110" Margin="5"/>
    </StackPanel>

后台

  Binding binding = new Binding("Value") { Source = this.slider1 };
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            RangeValidationRule rvr = new RangeValidationRule();
            rvr.ValidatesOnTargetUpdated = true;
            binding.ValidationRules.Add(rvr);
            binding.NotifyOnValidationError = true;
            this.textBox1.SetBinding(TextBox.TextProperty, binding);
            this.textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));



void ValidationError(object sender,RoutedEventArgs e)
        {
            if (Validation.GetErrors(this.textBox1).Count>0)
            {
                this.textBox1.ToolTip = Validation.GetErrors(this.textBox1)[0].ErrorContent.ToString();
            }
        }

输入验证 

public class RangeValidationRule:ValidationRule
    {
        public override ValidationResult Validate(object value, 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");
        }
    }

6、转换器使用

前台

 <ListBox x:Name="listBoxPlane" Height="160" Margin="5">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Width="20" Height="20" Source="{Binding Path=Category,Converter={StaticResource cts}}"/>
                        <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80,0"/>
                        <CheckBox IsThreeState="True" IsChecked="{Binding Path=State,Converter={StaticResource stnb}}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

后台

关联数据源:

   List<Plane> planlist = new List<Plane>()
            {
                new Plane(){Category=Category.Bomber,Name="B-1",State=State.Unknown},
                new Plane(){Category=Category.Bomber,Name="B-2",State=State.Unknown},
                new Plane(){Category=Category.Fighter,Name="F-22",State=State.Unknown},
                new Plane(){Category=Category.Fighter,Name="Su-47",State=State.Unknown},
                new Plane(){Category=Category.Bomber,Name="B-52",State=State.Unknown},
                new Plane(){Category=Category.Fighter,Name="J-10",State=State.Unknown},
            };
            this.listBoxPlane.ItemsSource = planlist;

图像与枚举转换器

public class CategoryToSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Category c = (Category)value;
            switch (c)
            {
                case Category.Bomber:
                    return @"Icons\1.png";
                case Category.Fighter:
                    return @"Icons\2.png";
                default:
                    return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

复选框与状态转换器

public class StateToNullableBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            State s = (State)value;
            switch (s)
            {
                case State.Available:
                    return true;
                case State.Locked:
                    return false;
                case State.Unknown:
                default:
                    return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool? nb = (bool?)value;
            switch (nb)
            {
                case true:
                    return State.Available;
                case false:
                    return State.Locked;
                case null:
                default:
                    return State.Unknown;
            }
        }
    }

7、多值绑定

前台

 <StackPanel Background="LightBlue">
        <TextBox x:Name="tb1" Height="23" Margin="5"/>
        <TextBox x:Name="tb2" Height="23" Margin="5,0"/>
        <TextBox x:Name="tb3" Height="23" Margin="5"/>
        <TextBox x:Name="tb4" Height="23" Margin="5,0"/>
        <Button x:Name="button1" Content="Submit" Width="80" Margin="5"/>
    </StackPanel>

后台

 private void SetMulitBinding()
        {
            //准备基础Binding
            Binding b1 = new Binding("Text") { Source = this.tb1 };
            Binding b2 = new Binding("Text") { Source = this.tb2 };
            Binding b3 = new Binding("Text") { Source = this.tb3 };
            Binding b4 = new Binding("Text") { Source = this.tb4 };

            //准备MultiBinding 
            MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay };
            mb.Bindings.Add(b1);  //注意:MultiBinding对Add子Binding的顺序是敏感的
            mb.Bindings.Add(b2);
            mb.Bindings.Add(b3);
            mb.Bindings.Add(b4);

            //获取或设置用于在源值和目标值之间来回转换的转换器。
            mb.Converter = new LogonMultiBindingConverter();

            //将Buttion与MultiBinding对象关联
            this.button1.SetBinding(Button.IsEnabledProperty, mb);
        }

转换器

public class LogonMultiBindingConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (!values.Cast<string>().Any(text=>string.IsNullOrEmpty(text))
                &&values[0].ToString()==values[1].ToString()
                &&values[2].ToString()==values[3].ToString())
            {
                return true;
            }
            return false;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        
    }

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值