从viewmodel访问panel(view)对象

时间:2013-12-30 17:44:21

标签: c# .net wpf

我刚刚在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>

我想在下面的viewmodel中使用此代码来获取所选的radio btn。

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

问题是:如何从viewmodel访问此面板对象?这不是使用绑定的数据。

更新: 正如@Rohit Vatss所说“不应该从ViewModel访问View对象”我会将问题更改为如何知道使用viewmodel选择了哪个单选按钮?

2 个答案:

答案 0 :(得分:1)

您可以通过在ViewModel中创建一个属性来实现,简单地说GroupIndex

private int _groupIndex = 1;

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

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

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,这将被设置为1,2或3,具体取决于检查RadioButton

<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

答案 1 :(得分:0)

例如,使用与视频模型绑定的单选按钮上的命令和命令参数,可以使用一个命令。例如:

<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,以便您可以轻松地使用Property更改。

希望它有所帮助。