现在的位置: 首页 > 综合 > 正文

[WPF学习]数据绑定

2017年11月07日 ⁄ 综合 ⁄ 共 3355字 ⁄ 字号 评论关闭

前阵子朋友发来一个Demo,说还是用的WINFORM的思想在写WPF程序,让我给看看有何改进之处,程序原帖如下:

点击打开链接

主要代码还是在四个Slider上绑定同一个事件处理函数:

 private void sliderValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
        {
            byte a = (byte)(sliderA.Value);
            byte r = (byte)(sliderR.Value);
            byte g = (byte)(sliderG.Value);
            byte b = (byte)(sliderB.Value);

            Color clr = Color.FromArgb(a, r, g, b);

            demoArea.Fill = new SolidColorBrush(clr);
            txtColorValue.Text = clr.ToString();
        }

而似乎这直接可以用WPF的数据绑定来完成的。

算是帮朋友解决问题,也算是自己学习一下WPF,写了个小Demo。

首先第一想法是绑定方法。

使用ObjectDataProvider。

但是由于ObjectInstance属性需要一个实例,对此很是纳闷,对于静态方法这该如何?看来自己的C#基础还是没有学好啊。

也罢,于是自己写了个类,只有一个方法,来调用Color的FromArgb方法。

class MyClass
    {
        public Brush FromArgb(double a, double r, double g, double b)
        {
            return new SolidColorBrush(Color.FromArgb(Convert.ToByte(a), Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)));
        }
    }

然后,绑定:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        ObjectDataProvider odp = new ObjectDataProvider();

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            odp.ObjectInstance = new MyClass();
            odp.MethodName = "FromArgb";
            odp.MethodParameters.Add(0);
            odp.MethodParameters.Add(0);
            odp.MethodParameters.Add(0);
            odp.MethodParameters.Add(0);

            Binding bind0 = new Binding("MethodParameters[0]") 
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            Binding bind1 = new Binding("MethodParameters[1]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            Binding bind2 = new Binding("MethodParameters[2]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            Binding bind3 = new Binding("MethodParameters[3]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            Binding bindResult = new Binding(".") { Source = odp };

            this.sliderA.SetBinding(Slider.ValueProperty, bind0);
            this.sliderR.SetBinding(Slider.ValueProperty, bind1);
            this.sliderG.SetBinding(Slider.ValueProperty, bind2);
            this.sliderB.SetBinding(Slider.ValueProperty, bind3);

            this.rectColor.SetBinding(Grid.BackgroundProperty, bindResult);
        }
    }

这解决方法有点别扭,似乎有意为了绑定而绑定。

所以又做了思考,决定使用MultiBinding(多重绑定)

于是写下如下代码:

public class DoublesToBrushConverter : IMultiValueConverter
    {

        #region IMultiValueConverter 成员

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return new SolidColorBrush(Color.FromArgb(
                System.Convert.ToByte(values[0]), 
                System.Convert.ToByte(values[1]),
                System.Convert.ToByte(values[2]),
                System.Convert.ToByte(values[3])));
        }

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

        #endregion
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class Win1 : Window
    {
        public Win1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Binding bindA = new Binding("Value") { Source = this.sliderA };
            Binding bindR = new Binding("Value") { Source = this.sliderR };
            Binding bindG = new Binding("Value") { Source = this.sliderG };
            Binding bindB = new Binding("Value") { Source = this.sliderB };

            MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay };
            mb.Bindings.Add(bindA);
            mb.Bindings.Add(bindR);
            mb.Bindings.Add(bindG);
            mb.Bindings.Add(bindB);

            mb.Converter = new DoublesToBrushConverter();
            this.rectColor.SetBinding(Grid.BackgroundProperty, mb);
        }
    }

这样感觉顺眼多了,回头想想,问题主要出在Color的A、R、G、B属性“不能绑定”。

感觉这种问题应该有别的解决方法,因为可以“绑定资源”的。

想了想,未果。

决定先放在这里。用winform去做我没完成的XXX管理程序。哈哈。

示例下载

抱歉!评论已关闭.