C# 如何绑定到WPF中动态创建的单选按钮?
我正在开发的应用程序中使用WPF和MVVM 我动态创建了5个单选按钮,在创建时,我使用枚举和IValueConverter设置绑定 这没关系,因为我知道我只需要5个单选按钮,但是现在我需要创建的单选按钮的数量可以改变,可以是5个,也可以是30个 那么,用代码绑定单选按钮的最佳方法是什么?我想我不能再使用枚举了,除非我设法动态创建枚举,我不知道我读到的关于动态枚举的内容是否可能 谢谢 编辑 这里或多或少是我用来动态创建单选按钮的代码C# 如何绑定到WPF中动态创建的单选按钮?,c#,wpf,mvvm,binding,radio-button,C#,Wpf,Mvvm,Binding,Radio Button,我正在开发的应用程序中使用WPF和MVVM 我动态创建了5个单选按钮,在创建时,我使用枚举和IValueConverter设置绑定 这没关系,因为我知道我只需要5个单选按钮,但是现在我需要创建的单选按钮的数量可以改变,可以是5个,也可以是30个 那么,用代码绑定单选按钮的最佳方法是什么?我想我不能再使用枚举了,除非我设法动态创建枚举,我不知道我读到的关于动态枚举的内容是否可能 谢谢 编辑 这里或多或少是我用来动态创建单选按钮的代码 公共枚举映射选项{ 选项0, 选择1, 选择2, 选择3, 选择
公共枚举映射选项{
选项0,
选择1,
选择2,
选择3,
选择4
}
私有映射选项映射属性;
公共映射选项映射属性
{
获取{return mappingProperty;}
设置
{
mappingProperty=值;
base.RaisePropertyChanged(“MappingProperty”);
}
}
私有void CreateRadioButtons()
{
整数极限=5;
整数计数=0;
字符串groupName=“groupName”;
parent.FormWithRadioButtons.Children.Clear();
foreach(所有CustomValue中的CustomValue值)
{
如果(计数<限制)
{
System.Windows.Controls.RadioButton tmpRadioBtn=新的System.Windows.Controls.RadioButton();
tmpRadioBtn.DataContext=this;
tmpRadioBtn.Content=value.Name;
tmpRadioBtn.GroupName=GroupName;
tmpRadioBtn.Margin=新系统窗口厚度(10,0,0,5);
字符串参数=string.format(“选项{0}”,count.ToString());
System.Windows.Data.Binding tmpBinding=新的System.Windows.Data.Binding(“MappingProperty”);
tmpBinding.Converter=新的EnumBooleanConverter();
tmpBinding.ConverterParameter=参数;
tmpBinding.Source=这个;
尝试
{
tmpRadioBtn.SetBinding(System.Windows.Controls.RadioButton.IsCheckedProperty,tmpBinding);
}
捕获(例外情况除外)
{
//句柄解释
}
parent.FormWithRadioButtons.Children.Add(tmpRadioBtn);
计数+=1;
}
其他的
打破
}
MappingProperty=MappingOptions.Option0;
}
公共类EnumBooleanConverter:IValueConverter
{
#地区/地区转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
string parameterString=作为字符串的参数;
if(parameterString==null)
返回System.Windows.DependencyProperty.UnsetValue;
if(Enum.IsDefined(value.GetType(),value)==false)
返回System.Windows.DependencyProperty.UnsetValue;
object parameterValue=Enum.Parse(value.GetType(),parameterString);
返回参数value.Equals(值);
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
string parameterString=参数为字符串;
if(parameterString==null)
返回System.Windows.DependencyProperty.UnsetValue;
返回Enum.Parse(targetType,parameterString);
}
#端区
}
创建一个类,该类公开stringText
和booleanIsChecked
属性,并实现INotifyPropertyChanged
。称之为MutexViewModel
创建另一个类,该类实现这些对象的可观察集合,称为互斥体
,并在每个对象上处理属性更改
,例如,具有如下构造函数:
public MutexesViewModel(IEnumerable<MutexViewModel> mutexes)
{
_Mutexes = new ObservableCollection<MutexViewModel>();
foreach (MutexViewModel m in Mutexes)
{
_Mutexes.Add(m);
m.PropertyChanged += MutexViewModel_PropertyChanged;
}
}
现在,您有了一种机制,可以创建任意数量的命名布尔属性,这些属性都是互斥的,即在任何给定时间,它们中只能有一个是真的
现在像这样创建XAML—这是一个MutexesViewModel
对象的DataContext
,但是您也可以将ItemsSource
绑定到类似{DynamicResource mymutexviewmodel.mutex}
的对象
<ItemsControl ItemsSource="{Binding Mutexes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:MutexViewModel">
<RadioButton Content="{Binding Text}" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
请发布一些代码,以便我们了解您绑定到的内容。您好,谢谢您的回答,但我不认为我可以用它来解决我的问题,因为我需要从代码而不是从XAML创建单选按钮,我尝试使用您建议的类,并将其与我上面发布的代码相结合,但没有效果……完全没有必要从代码中创建这些单选按钮。请看我的编辑。非常感谢,我不知道为什么我第一次尝试时它不起作用,但今天当我再次尝试时,它起了很大的作用!
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;
}
}
<ItemsControl ItemsSource="{Binding Mutexes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:MutexViewModel">
<RadioButton Content="{Binding Text}" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
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; }
}
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);
}