【问题标题】:accessing to panel (view) object from the viewmodel从视图模型访问面板(视图)对象
【发布时间】:2013-12-30 17:44:20
【问题描述】:

我刚刚在 youtube 上观看了实用的 mvvm 演示视频,如果我理解正确,将逻辑从代码行为转移到视图模型是一种很好的做法,我们应该努力实现这种模式。

考虑到这一点,我有一个简单的问题。在 xaml 中,我有四个单选按钮

<StackPanel x:Name="panel">
    <RadioButton GroupName="myGroup" Name="Option1" Content="option one" IsChecked="True"  Width="40"/>
     <RadioButton GroupName="myGroup" Name="Option2" Content="option two" IsChecked="False" Width="80"/>
     <RadioButton GroupName="myGroup" Name="Option3" Content="option three" IsChecked="False" Width="60"/>
</StackPanel>

我想在下面的视图模型中使用此代码来获取选定的收音机 btn。

var checkedValue = panel.Children.OfType<RadioButton>()
                 .FirstOrDefault(r => r.IsChecked.HasValue && r.IsChecked.Value);

问题是:如何从视图模型访问此面板对象?使用绑定的不是数据。

更新: 正如@Rohit Vatss 所说“不应从 ViewModel 访问视图对象”,我会将问题更改为 How to know which radio button are selected using viewmodel?

【问题讨论】:

  • 根据 MVVM 模式 - 不应从 ViewModel 访问视图对象。这违反了 MVVM 模式。
  • @Rohit Vats 谢谢,刚刚更新的问题

标签: c# .net wpf


【解决方案1】:

您可以通过在 ViewModel 中创建一个属性来做到这一点,比如说GroupIndex

private int _groupIndex = 1;

public int GroupIndex
{
   get { return _groupIndex; }
   set
   {
      if (_groupIndex == value) return;
      _groupIndex = value;
      OnPropertyChanged("GroupIndex");
   }
}

然后创建简单的转换器,它将当前GroupIndex 值转换为真或假并返回:

public class IndexBooleanConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
     if (value == null || parameter == null)
        return false;
     else
        return (int)value == System.Convert.ToInt32(parameter);
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
     if (value == null || parameter == null)
         return null;
     else if ((bool)value)
         return System.Convert.ToInt32(parameter);
     else
         return DependencyProperty.UnsetValue;
  }
}   

然后将您的 RadioButton 绑定到 GroupIndex,这将根据选中的 RadioButton 设置为 1、2 或 3

<StackPanel>
  <StackPanel.Resources>
      <local:IndexBooleanConverter x:Key="IndexBooleanConverter"/>
  </StackPanel.Resources>
  <RadioButton Content="Option1" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=1}"/>
  <RadioButton Content="Option2" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=2}"/>
  <RadioButton Content="Option3" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=3}"/>
</StackPanel>

在这种情况下,GroupIndexint,但您也可以使用相同的逻辑,例如您的 GroupIndexenum

【讨论】:

    【解决方案2】:

    例如,一个方法是在绑定到您的视图模型的单选按钮上使用命令和命令参数。例如:

    <RadioButton GroupName="myGroup" Name="Option1" Content="option one" IsChecked="True"  Width="40" Command="{Binding RbCheckedCommand}" CommandParameter="RB1"/>
         <RadioButton GroupName="myGroup" Name="Option2" Content="option two" IsChecked="False" Width="80" Command="{Binding RbCheckedCommand}" CommandParameter="RB2"/>
         <RadioButton GroupName="myGroup" Name="Option3" Content="option three" IsChecked="False" Width="60" Command="{Binding RbCheckedCommand}" CommandParameter="RB3"/>
    

    然后在您的 ViewModel 上:

    private readonly DelegateCommand<object> rbCheckedCommand;
    
    public ICommand RbCheckedCommand
    {
        get { return this.rbCheckedCommand; }
    }
    
    
    private void RbCheckedCommandExecute(object obj)
    {
        string rbselected = obj.ToString();
    }
    

    关于类的构造函数:

    this.rbCheckedCommand = new DelegateCommand<object>(RbCheckedCommandExecute);
    

    您将不得不使用棱镜添加:

    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.ViewModel;
    

    并让您的类继承自 NotificationObject,以便您可以轻松使用更改的属性。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2018-06-24
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      相关资源
      最近更新 更多