如何区分MVVM中的相同控件?

时间:2015-05-11 16:11:27

标签: c# wpf mvvm

我有5 CheckBox这就是他们在View中的样子:

<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Content="Cb1"/>
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Content="Cb2"/>
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Content="Cb3"/>
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Content="Cb4"/>
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Content="Cb5"/>

这是我ViewModel中的一些代码:

class CheckBoxesViewModel : INotifyPropertyChanged
{
public CheckBoxesViewModel()
{
    CheckBoxes= new ObservableCollection<Models.CheckBoxes>();
    _canExecute = true;
}

private bool _IsSelected;
public bool IsSelected
{
    get
    {
        return _IsSelected;
    }
    set
    {
        _IsSelected = value;
        OnPropertyChanged("IsSelected");
    }
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

private ObservableCollection<Models.CheckBoxes> _checkBoxes = new ObservableCollection<Models.CheckBoxes>();
public ObservableCollection<Models.CheckBoxes> CheckBoxes
{
    get { return _checkBoxes ; }
    set
    {
        _checkBoxes = value;
        OnPropertyChanged("CheckBoxes");
    }
}
}

问题在于,当我选中/取消选中其中一个复选框时,它会影响所有复选框。

我认为这是因为它们具有完全相同的绑定,但我无法弄清楚如何使代码区分它们。

我想我可以使用CommandCommandParameters,但这似乎不是最佳解决方案。

P.S。如果你发现我的代码有问题,请告诉我 - 我仍在尝试学习整个MVVM。

3 个答案:

答案 0 :(得分:1)

您需要实现ICommand(google DelegateCommand才能将Action视为ICommand)然后您将视图中CheckBox的Command属性绑定到视图模型上的Command。

视图模型

public ICommand MyCommand { get; private set; }
.... MyCommand = new DelegateCommand((value) => this.DoStuff(value));

的Xaml

<CheckBox Command={Binding MyCommand} Command Parameter={...} />

答案 1 :(得分:1)

根据您在评论中陈述的目的(这应该是您的问题 - 这是一个经典的XY problem

您正在尝试通过ViewModel路由View逻辑,这应该暗示这里出了问题。你声明的目的是

  

每个CheckBox都有一个相应的TextBox,在选中时会显示它。我希望为所有CheckBox重用相同的代码,只改变一些值,以帮助我区分它们(例如内容)

切换可见性是一个视图问题。你可以这样做

<StackPanel>
    <CheckBox x:Name = "cb1" />
    <!-- cb2 through cbn omitted -->
<StackPanel />
<StackPanel>
<StackPanel.Resources>
    <BooleanToVisibilityConverter x:Key="btvc" />
</StackPanel.Resources>
    <TextBox Text="{Binding FirstTextBox}"
             Visibility="{Binding IsChecked, 
                                  ElementName=cb1, 
                                  Converter={StaticResource btvc}}" />
    <!-- SecondTextBox through NthTextBox omitted -->
</StackPanel />

我是否通过检查相应的复选框来切换文本框的可见性。

现在,如果你试图将N个文本框值合并到一个属性中......你的生活太过艰难了。

答案 2 :(得分:0)

如果您希望以编程方式添加它们&#34;,那么您需要撤消逻辑。而不是添加控件&#39;在表单中,您需要考虑添加数据&#39;到您的ViewModel。正如您的标记所示,这就是您遵守MVVM指南的方式。

这里是如何反转逻辑的.... ItemsControl能够绑定到ViewModel的集合。这种控制也是“自动化”的。使用DataTemplates确定要对集合中的每个项使用什么控件。

这是XAML代码:

<ItemsControl ItemsSource="{Binding myCollection}" >
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type local:myViewModelForItemA}">
            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding aName}"></CheckBox>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:myViewModelForItemB}">
            <RadioButton IsChecked="{Binding IsChecked}" Content="{Binding aName}"></RadioButton>
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>

正如你可能看到的那样,Binding&#34; myCollection&#34;是您将ViewModel实例添加到的集合(这是一个ObservableCollection)。

IntemsControl.Resources中的每个DataTemplate都是你希望每个项目看起来的样子(你甚至可以在每个DataTemplate中放置多个控件,只要记住你绑定它们的任何内容都将绑定到集合中的ViewModel(即myViewModelForItemA,myViewModelForItemB) )。

主视图模型中的代码:

public ObservableCollection<object> myCollection { set; get; } 

....

myCollection = new ObservableCollection<object>();
myViewModelForItemA anItem = new myViewModelForItemA();
myCollection.Add(anItem);
//now anItem of type (myViewModelForItemA) is in our collection
//and the ItemsControl automagically added a CheckBox to it's collection
//and bound isChecked to anItem.isChecked property, and bound
//the Content to anItem.aName property.