WPF MVVM Radio buttons on ItemsControl

前端 未结 4 742
予麋鹿
予麋鹿 2020-12-08 11:08

I\'ve bound enums to radio buttons before, and I generally understand how it works. I used the alternate implementation from this question: How to bind RadioButtons to an e

4条回答
  •  悲&欢浪女
    2020-12-08 11:22

    As far as I know, there's no good way to do this with a MultiBinding, although you initially think there would be. Since you can't bind the ConverterParameter, your ConvertBack implementation doesn't have the information it needs.

    What I have done is created a separate EnumModel class solely for the purpose of binding an enum to radio buttons. Use a converter on the ItemsSource property and then you're binding to an EnumModel. The EnumModel is just a forwarder object to make binding possible. It holds one possible value of the enum and a reference to the viewmodel so it can translate a property on the viewmodel to and from a boolean.

    Here's an untested but generic version:

    
        
            
                
                    
                
            
        
    
    

    The converter:

    public class ToEnumModelsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var viewmodel = value;
            var prop = viewmodel.GetType().GetProperty(parameter as string);
    
            List enumModels = new List();
    
            foreach(var enumValue in Enum.GetValues(prop.PropertyType))
            {
                var enumModel = new EnumModel(enumValue, viewmodel, prop);
                enumModels.Add(enumModel);
            }
    
            return enumModels;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    The EnumModel:

    public class EnumModel : INPC
    {
        object enumValue;
        INotifyPropertyChanged viewmodel;
        PropertyInfo property;
    
        public EnumModel(object enumValue, object viewmodel, PropertyInfo property)
        {
            this.enumValue = enumValue;
            this.viewmodel = viewmodel as INotifyPropertyChanged;
            this.property = property;
    
            this.viewmodel.PropertyChanged += new PropertyChangedEventHandler(viewmodel_PropertyChanged);
        }
    
        void viewmodel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == property.Name)
            {
                OnPropertyChanged("IsChecked");
            }
        }
    
        public bool IsChecked
        {
            get
            {
                return property.GetValue(viewmodel, null).Equals(enumValue);
            }
            set
            {
                if (value)
                {
                    property.SetValue(viewmodel, enumValue, null);
                }
            }
        }
    }
    

    For a code sample that I know works (but it's still quite unpolished - WIP!), you can see http://code.google.com/p/pdx/source/browse/trunk/PDX/PDX/Toolkit/EnumControl.xaml.cs. This only works within the context of my library, but it demonstrates setting the Name of the EnumModel based on the DescriptionAttribute, which might be useful to you.

提交回复
热议问题