如何从视图模型更新视图中的单选按钮
本文关键字:新视图 单选按钮 更新 模型 视图 | 更新日期: 2023-09-27 18:28:10
假设我的视图中有几个单选按钮组合在一起.xaml:
<RadioButton GroupName="Group" Content="Item1" Command="{Binding ChangeRadioSelectionCommand}" CommandParameter="Item1" />
<RadioButton GroupName="Group" Content="Item2" Command="{Binding ChangeRadioSelectionCommand}" CommandParameter="Item2" />
<RadioButton GroupName="Group" Content="Item3" Command="{Binding ChangeRadioSelectionCommand}" CommandParameter="Item3" />
然后在我的viewmodel.cs
中,我有一些类似的东西:
public class ViewModel : BindableBase
{
private string radioSelection = "Item1";
public string RadioSelection
{
get { return this.radioSelection; }
set { SetProperty(ref this.radioSelection, value); }
}
public ViewModel()
{
this.ChangeRadioSelectionCommand = new DelegateCommand<string>(this.OnChangeRadioSelection, this.CanChangeRadioSelection);
}
public ICommand ChangeRadioSelectionCommand { get; private set; }
private void OnChangeRadioSelection(string radioSelection)
{
RadioSelection = radioSelection;
}
private bool CanChangeRadioSelection(string radioSelection) { return true; }
}
这对于将值从视图获取到视图模型非常有效,但如果视图模型发生了变化,我该如何从视图模型转到视图。为了简单起见,假设我在xaml:中添加了一个按钮
<Button Command="{Binding ResetRadioSelectionCommand}" />
它所要做的就是将无线电选择重置为第一项,因此viewmodel.cs
看起来像:
public class ViewModel : BindableBase
{
private string radioSelection = "Item1";
public string RadioSelection
{
get { return this.radioSelection; }
set { SetProperty(ref this.radioSelection, value); }
}
public ViewModel()
{
this.ChangeRadioSelectionCommand = new DelegateCommand<string>(this.OnChangeRadioSelection, this.CanChangeRadioSelection);
this.ResetRadioSelectionCommand = new DelegateCommand(this.OnResetRadioSelection, this.CanResetRadioSelection);
}
public ICommand ChangeRadioSelectionCommand { get; private set; }
private void OnChangeRadioSelection(string radioSelection)
{
RadioSelection = radioSelection;
}
private bool CanChangeRadioSelection(string radioSelection) { return true; }
public ICommand ResetRadioSelectionCommand { get; private set; }
private void OnResetRadioSelection()
{
RadioSelection = "Item1";
}
private bool CanResetRadioSelection() { return true; }
}
这将更改radioSelection,但它不会反映在gui中。有办法做到这一点吗?或者也许只是一种更好的方式来处理一般的单选按钮?
这完全是错误的方式。ViewModel应该包含一个具有合理名称的合理属性。例如CurrentMode。
第一个解决方案
ViewModel
public enum DisplayMode { Vertical, Horizontal, Diagonal }
private DisplayMode currentMode;
public DisplayMode CurrentMode
{
get { return currentMode; }
set { SetProperty(ref currentMode, value); }
}
现在您可以通过IValueConverter:将此属性绑定到RadioButton.IsChecked
<RadioButton GroupName="Group" Content="Vertical" IsChecked="{Binding CurrentMode, Converter={StaticResource enumToBoolConverter}, ConverterParameter=Vertical}" />
<RadioButton GroupName="Group" Content="Horizontal" IsChecked="{Binding CurrentMode, Converter={StaticResource enumToBoolConverter}, ConverterParameter=Horizontal}" />
<RadioButton GroupName="Group" Content="Diagonal" IsChecked="{Binding CurrentMode, Converter={StaticResource enumToBoolConverter}, ConverterParameter=Diagonal}" />
转换器对所有枚举都是通用的。您需要将它添加到您的项目中,并在视图的资源块中声明。
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 DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return 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 DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
#endregion
}
这是众多解决方案之一。您可能不希望我们为您的属性枚举,因为主题区域未映射到参数枚举。然后您可以绑定到文本值:
第二个解决方案
ViewModel
private string currentMode;
public string CurrentMode
{
get { return currentMode; }
set { SetProperty(ref currentMode, value); }
}
查看
<RadioButton Name="RadioButton1"
GroupName="Group"
Content="Vertical"
IsChecked="{Binding Path=CurrentMode, Converter={StaticResource boolToStringValueConverter}, ConverterParameter=Vertical}" />
<RadioButton Name="RadioButton2"
GroupName="Group"
Content="Horizontal"
IsChecked="{Binding Path=CurrentMode, Converter={StaticResource boolToStringValueConverter}, ConverterParameter=Horizontal}" />
<RadioButton Name="RadioButton3"
GroupName="Group"
Content="Diagonal"
IsChecked="{Binding Path=CurrentMode, Converter={StaticResource boolToStringValueConverter}, ConverterParameter=Diagonal}" />
转换器
public class BooleanToStringValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (System.Convert.ToString(value).Equals(System.Convert.ToString(parameter)))
{
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (System.Convert.ToBoolean(value))
{
return parameter;
}
return null;
}
}
一般原则是在ViewModels中存储主题区域的有意义投影。如果要在ViewModel中保留视图属性的存储副本,那就没有什么意义了。RadioSelection是一个毫无意义的名字,如果没有额外的注释,它就无法与模型相关联。