none
WPF中当一个类中数值发生变化后,触发事件。如何完成? RRS feed

  • 问题

  • 比如person类中有一个 age属性

    age会不停的变化

    当age<18时,我usercontrol中image 显示一张小孩的图片

    当age>18&&age<50  显示一张大人图片

    当age>50时 显示一张老人图片

    就是怎样去判断一个数据的变化,然后去触发对应的事件哪???

    2017年10月31日 8:15

答案

  • Hi,

    你应该需要的是值转换器。

     public class ImageConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if ((int)value < 18)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"child.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                if ((int)value >= 18 && (int)value < 50)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"adult.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                if ((int)value >= 50)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"OldMan.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                else
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"placeholder.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
     <Image
                Width="200"
                Height="200"
                Margin="0"
                Source="{Binding Age, Converter={StaticResource imageConverter}}"
                Stretch="Uniform" />

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2017年11月1日 9:01
    版主

全部回复

  • Hi,

    你应该需要的是值转换器。

     public class ImageConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if ((int)value < 18)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"child.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                if ((int)value >= 18 && (int)value < 50)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"adult.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                if ((int)value >= 50)
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"OldMan.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
                else
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.UriSource = new Uri(@"placeholder.jpg", UriKind.RelativeOrAbsolute);
                    bi.EndInit();
                    return bi;
                }
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
     <Image
                Width="200"
                Height="200"
                Margin="0"
                Source="{Binding Age, Converter={StaticResource imageConverter}}"
                Stretch="Uniform" />

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2017年11月1日 9:01
    版主
  • 谢谢你的回复

    但是我遇到了一个新的问题

    如果我的age属性是一个int[] ,我下面的写法不能实现图片的转换。

    第一种写法:

    class person: INotifyPropertyChanged
        {
    System.Timers.Timer time = new System.Timers.Timer(1000);
            private int[] age = new int[100];    
            public person()
            {
                time.Elapsed += new System.Timers.ElapsedEventHandler(getInfo);
                time.AutoReset = true;//自动触发
                time.Enabled = true;//启用计时器
            }
    
            //注册绑定属性
            public event PropertyChangedEventHandler PropertyChanged;
            public int[] Age
            {
                get { return age; }
                set
                {
                    age = value;
                    if (this.PropertyChanged != null)
                    {
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
                        // 通知Binding是“Age”这个属性的值改变了
                    }
                }
            }      
            public void getInfo(object source, System.Timers.ElapsedEventArgs e)
            {
                Age[0] += 1;
            }
        }
    <UserControl.Resources>
            <local:person  x:Key="Personage"></local:person>
            <local:ImageConverter x:Key="image"></local:ImageConverter>
     </UserControl.Resources>
    <Image  Source="{Binding Source={StaticResource Personage},Path=Age[0],Converter={StaticResource image}}"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  Width="35" />

    第二种写法:

    只有改写成这样才能实现图片的变化.

    //注册绑定属性
            public event PropertyChangedEventHandler PropertyChanged;
            public int Age
            {
                get { return age[0]; }
                set
                {
                    age[0] = value;
                    if (this.PropertyChanged != null)
                    {
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
                        // 通知Binding是“Age”这个属性的值改变了
                    }
                }
            }      
            public void getInfo(object source, System.Timers.ElapsedEventArgs e)
            {
                Age += 1;
            }
    <UserControl.Resources>
            <local:person  x:Key="Personage"></local:person>
            <local:ImageConverter x:Key="image"></local:ImageConverter>
     </UserControl.Resources>
    <Image  Source="{Binding Source={StaticResource Personage},Path=Age,Converter={StaticResource image}}"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  Width="35" />

    虽然第二种写法可以完成这个功能,但是如果有多个图片,需要绑定的同一数组内不同的数据的话,这个方法很麻烦。

    所以我想问一下有没有多个image一次性绑定一个数组中相应数据的方法哪???

    2017年11月2日 13:01
  • Hi,

    虽然不清楚你的具体需求是怎样的,为什么Age属性是一个数组,你可能需要绑定到两个或以上的数据源。

    同时绑定数组,和数组的索引向下面所示。

    <MultiBinding Converter="{StaticResource ImageConverter}">
         <Binding Path="AgeIndex" />
          <Binding Path="Age"/>
    </MultiBinding>
    public class ImageConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (values == null )
                    return null;
                var index = values[0];
                var age = value[1];
               //做相应的判断
                return ;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月3日 4:50
    版主
  • 我的意思是

    最开始是一张image对应一个int age

    现在如果是N张image的话就是对应一个int【N】age

    N如果少的话还好,如果要创建N个数据源的话太麻烦了,所以我想问一下怎么去简便的实现??

    2017年11月3日 6:20
  • 再举个例子就是

    第一个image绑定age[0],第二个iamge绑定age[1]………………第N个image绑定age[N]

    //注册绑定属性 第一种方法 这种写法我发现当数据改变的时候,界面上的数据并没有改变
            public event PropertyChangedEventHandler PropertyChanged;
            public int[] Age
            {
                get { return age; }
                set
                {
                    age = value;
                    if (this.PropertyChanged != null)
                    {
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
                        // 通知Binding是“Age”这个属性的值改变了
                    }
                }
            }      
            public void getInfo(object source, System.Timers.ElapsedEventArgs e)
            {
                Age[0] += 1;
            }

    //注册绑定属性 这种写法可以实现改变,但是如果有N个image的话我就要写N个Age这样太麻烦了:(
            public event PropertyChangedEventHandler PropertyChanged;
            public int Age
            {
                get { return age[0]; }
                set
                {
                    age[0] = value;
                    if (this.PropertyChanged != null)
                    {
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
                        // 通知Binding是“Age”这个属性的值改变了
                    }
                }
            }      
            public void getInfo(object source, System.Timers.ElapsedEventArgs e)
            {
                Age += 1;
            }

    2017年11月3日 7:36