WPF使用MVVM模式时如何为动态生成的RadioButton应用指定主题
实现方案
方案1:遵循MVVM规范的推荐写法
你当前的实现存在不符合MVVM规范的问题:ViewModel层不应该存放任何UI控件实例,建议先把RadioButton的业务属性抽象为独立模型,再在XAML层统一绑定样式。
- 首先创建业务模型类:
public class MenuOptionModel : ObservableObject { private string _content; public string Content { get => _content; set { _content = value; OnPropertyChanged(); } } private bool _isChecked; public bool IsChecked { get => _isChecked; set { _isChecked = value; OnPropertyChanged(); } } }
- 调整ViewModel中的集合定义,替换掉控件类型的集合:
class ContentViewModel : ObservableObject { private int numScripts; // 替换为业务模型集合 public ObservableCollection<MenuOptionModel> SP { get; set; } public ContentViewModel() { numScripts = 5; // 该数值不固定为5 SP = new ObservableCollection<MenuOptionModel>(); CreateRadioButtons(numScripts); } public void CreateRadioButtons(int n) { for (int i = 0; i < n; i++) { // 只添加业务数据,不创建UI控件 SP.Add(new MenuOptionModel { Content = $"Radiobutton {i+1}" }); } } }
- 直接在XAML的ItemTemplate中指定样式,同时绑定命令和属性:
<StackPanel> <ItemsControl ItemsSource="{Binding SP}"> <ItemsControl.ItemTemplate> <DataTemplate> <RadioButton Content="{Binding Content}" IsChecked="{Binding IsChecked}" Style="{StaticResource MenuButtonTheme}" <!-- 用RelativeSource获取外层ViewModel的命令 --> Command="{Binding DataContext.ContentViewCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel>
方案2:不修改现有逻辑的临时实现
如果你暂时不打算调整现有ViewModel放控件的写法,也可以在创建RadioButton时直接从资源中获取样式赋值:
public void CreateRadioButtons(int n) { for (int i = 0; i < n; i++) { RadioButton rb = new() { Content = "Radiobutton", Foreground = Brushes.AntiqueWhite, // 从全局资源中加载样式,如果是页面级资源就用当前页面的Resources查找 Style = (Style)Application.Current.Resources["MenuButtonTheme"] }; SP.Add(rb); } }
注意:该方案不符合MVVM分层原则,仅适合临时调试使用,不推荐生产环境使用
内容的提问来源于stack exchange,提问作者sbrownCD
相关产品推荐
相关产品推荐

