[英]How to bind to radio buttons created dynamically in WPF?
我在我正在使用的應用程序中使用WPF和MVVM。
我正在動態創建5個單選按鈕,在創建時我使用枚舉和IValueConverter設置綁定。
這沒關系,因為我知道我只需要5個單選按鈕,但現在我需要創建的單選按鈕的數量可以改變,它們可以是5,因為它們可能是30。
那么,這是將單選按鈕與代碼綁定的最佳方法? 我想我不能再使用枚舉了,除非我設法動態創建枚舉,我不知道是否有可能我讀到有關動態枚舉的內容......
謝謝。
編輯
這里或多或少是我用來動態創建單選按鈕的代碼。
public enum MappingOptions {
Option0,
Option1,
Option2,
Option3,
Option4
}
private MappingOptions mappingProperty;
public MappingOptions MappingProperty
{
get { return mappingProperty; }
set
{
mappingProperty= value;
base.RaisePropertyChanged("MappingProperty");
}
}
private void CreateRadioButtons()
{
int limit = 5;
int count = 0;
string groupName = "groupName";
parent.FormWithRadioButtons.Children.Clear();
foreach (CustomValue value in AllCustomValues)
{
if (count < limit)
{
System.Windows.Controls.RadioButton tmpRadioBtn = new System.Windows.Controls.RadioButton();
tmpRadioBtn.DataContext = this;
tmpRadioBtn.Content = value.Name;
tmpRadioBtn.GroupName = groupName;
tmpRadioBtn.Margin = new System.Windows.Thickness(10, 0, 0, 5);
string parameter = string.format("Option{0}", count.ToString());
System.Windows.Data.Binding tmpBinding = new System.Windows.Data.Binding("MappingProperty");
tmpBinding.Converter = new EnumBooleanConverter();
tmpBinding.ConverterParameter = parameter;
tmpBinding.Source = this;
try
{
tmpRadioBtn.SetBinding(System.Windows.Controls.RadioButton.IsCheckedProperty, tmpBinding);
}
catch (Exception ex)
{
//handle exeption
}
parent.FormWithRadioButtons.Children.Add(tmpRadioBtn);
count += 1;
}
else
break;
}
MappingProperty = MappingOptions.Option0;
}
public class EnumBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return System.Windows.DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return System.Windows.DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return System.Windows.DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
#endregion
}
創建一個公開字符串Text
和布爾IsChecked
屬性並實現INotifyPropertyChanged
。 叫它,哦, MutexViewModel
。
創建另一個實現這些對象的可觀察集合的類,稱為Mutexes
,並在每個對象上處理PropertyChanged
- 例如,有一個構造函數,如:
public MutexesViewModel(IEnumerable<MutexViewModel> mutexes)
{
_Mutexes = new ObservableCollection<MutexViewModel>();
foreach (MutexViewModel m in Mutexes)
{
_Mutexes.Add(m);
m.PropertyChanged += MutexViewModel_PropertyChanged;
}
}
和一個事件處理程序,確保在任何給定時間只有一個子對象的IsChecked
設置為true:
private void MutexViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MutexViewModel m = (MutexViewModel)sender;
if (e.PropertyName != "IsChecked" || !m.IsChecked)
{
return;
}
foreach (MutexViewModel other in _Mutexes.Where(x: x != m))
{
other.IsChecked = false;
}
}
您現在有一種機制可以創建任意數量的命名布爾屬性,這些屬性都是互斥的,即在任何給定時間只能有一個屬性為真。
現在像這樣創建XAML - 這個的DataContext
是一個MutexesViewModel
對象,但你也可以將ItemsSource
綁定到類似{DynamicResource myMutexesViewModel.Mutexes}
東西。
<ItemsControl ItemsSource="{Binding Mutexes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:MutexViewModel">
<RadioButton Content="{Binding Text}" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
編輯
我發布的XAML中存在語法錯誤,但沒有什么可以讓你完全停止。 這些類有效:
public class MutexViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Text { get; set; }
private bool _IsChecked;
public bool IsChecked
{
get { return _IsChecked; }
set
{
if (value != _IsChecked)
{
_IsChecked = value;
OnPropertyChanged("IsChecked");
}
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler h = PropertyChanged;
if (h != null)
{
h(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class MutexesViewModel
{
public MutexesViewModel(IEnumerable<MutexViewModel>mutexes)
{
Mutexes = new ObservableCollection<MutexViewModel>(mutexes);
foreach (var m in Mutexes)
{
m.PropertyChanged += MutexViewModel_PropertyChanged;
}
}
private void MutexViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MutexViewModel m = (MutexViewModel) sender;
if (e.PropertyName == "IsChecked" && m.IsChecked)
{
foreach(var other in Mutexes.Where(x => x != m))
{
other.IsChecked = false;
}
}
}
public ObservableCollection<MutexViewModel> Mutexes { get; set; }
}
創建一個項目,添加這些類,將ItemsControl
XAML粘貼到主窗口的XAML中,並將其添加到主窗口的代碼隱藏中:
public enum Test
{
Foo,
Bar,
Baz,
Bat
} ;
public MainWindow()
{
InitializeComponent();
var mutexes = Enumerable.Range(0, 4)
.Select(x => new MutexViewModel
{ Text = Enum.GetName(typeof (Test), x) });
DataContext = new MutexesViewModel(mutexes);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.