C# 如何从viewmodel更新视图中的单选按钮?

C# 如何从viewmodel更新视图中的单选按钮?,c#,wpf,mvvm,data-binding,prism,C#,Wpf,Mvvm,Data Binding,Prism,假设在我的view.xaml中有几个单选按钮组合在一起: <RadioButton GroupName="Group" Content="Item1" Command="{Binding ChangeRadioSelectionCommand}" CommandParameter="Item1" /> <RadioButton GroupName="Group" Content="Item2" Command="{Binding ChangeRadioSelectionComm

假设在我的view.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非常有效,但是如果viewmodel中发生更改,如何从viewmodel转到视图中呢。为了简单起见,假设我在xaml中添加了一个按钮:

<Button Command="{Binding ResetRadioSelectionCommand}" />

这将改变您的选择,但它不会反映在gui中。有办法做到这一点吗?或者也许只是一种更好的处理单选按钮的方法?

这是完全错误的方法。您的ViewModel应该包含具有合理名称的合理属性。例如,CurrentMode

第一个解决方案

视图模型

public enum DisplayMode { Vertical, Horizontal, Diagonal }

private DisplayMode currentMode;
public DisplayMode CurrentMode
{
    get { return currentMode; }
    set { SetProperty(ref currentMode, value); }
}
private string currentMode;
public string CurrentMode
{
    get { return currentMode; }
    set { SetProperty(ref currentMode, value); }
}
现在,您可以通过以下方式将此属性绑定到:

这是众多解决方案之一。您可能不希望为您的属性使用枚举,因为主题区域未映射到参数枚举。然后可以绑定到文本值:

第二种解决方案

视图模型

public enum DisplayMode { Vertical, Horizontal, Diagonal }

private DisplayMode currentMode;
public DisplayMode CurrentMode
{
    get { return currentMode; }
    set { SetProperty(ref currentMode, value); }
}
private string currentMode;
public string CurrentMode
{
    get { return currentMode; }
    set { SetProperty(ref currentMode, value); }
}
看法


一般原则是在ViewModels中存储主题区域的有意义投影。如果将视图属性的存储副本保留在ViewModel中,则没有多大意义。RadioSelection是一个无意义的名称,如果没有附加注释,它无法与模型关联。

您所说的“您的ViewModel应该包含一个具有合理名称的合理属性”是什么意思?在prism mvvm实践和模式中,转换方法现在仍然是必要的吗。我的意思是,财产名称应该是明确的主题领域,而不是你的观点(如按钮,单选组等)2。是的,转换器是mvvm应用程序的主要部分,无论是Prism、mvvm light还是其他框架。是的,我只是给出了通用名称,因为它只是一个示例。我无意中发现了一种用单选按钮解决绑定问题的方法。你对这些方法有什么看法吗?我不太记得这个问题。net 4.0已经存在了5年,WinXP支持.net 4.0,那么我可能从来没有在.net 3.5中使用过wpf,因为直到2011年才使用winforms。但是这篇文章包含的解决方案很少,它们不适合吗?带有自定义模板的chckbox将来可能会成为一个问题,但带有继承样式的继承radiobutton不是问题,不是吗?
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
}
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;
    }
}