我有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");
}
}
}
问题在于,当我选中/取消选中其中一个复选框时,它会影响所有复选框。
我认为这是因为它们具有完全相同的绑定,但我无法弄清楚如何使代码区分它们。
我想我可以使用Command
和CommandParameters
,但这似乎不是最佳解决方案。
P.S。如果你发现我的代码有问题,请告诉我 - 我仍在尝试学习整个MVVM。
答案 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.