我对WPF& MVVM,我在面板上有3个CheckBox项,我需要每当用户点击其中一个时,将调用一个方法。此方法应检查3 CheckBox中的每一个的状态(其中一个是'已检查',哪个是'未选中')并使用此信息在TextBlock上显示一些文本。例如,如果所有3个都被选中,它将显示“A”,如果所有这些都是未选中则显示“B”。
我对此并不复杂,希望你能帮助我。
以下是XAML代码:
<StackPanel>
<ItemsControl Margin="5" ItemsSource="{Binding Path=CheckBoxCollection, Mode=TwoWay}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=CheckBoxValue, Mode=TwoWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock>Result Here</TextBlock>
</StackPanel>
以下是代码:
public class CheckBoxValue
{
bool _theValue;
public bool theValue
{
get
{
return _theValue;
}
set
{
_theValue = value;
}
}
}
public class myViewModel : ViewModelBase
{
public ObservableCollection<CheckBoxValue> CheckBoxCollection { get; set; }
public myViewModel( Some Parameters.... )
{
CheckBoxCollection = new ObservableCollection<CheckBoxValue>();
CheckBoxCollection.Add(new CheckBoxValue { theValue = false });
CheckBoxCollection.Add(new CheckBoxValue { theValue = false });
CheckBoxCollection.Add(new CheckBoxValue { theValue = false });
base.RaisePropertyChanged( () => CheckBoxCollection );
}
}
答案 0 :(得分:1)
我更进一步为所有类型的“可选择”事物定义可重用的ViewModel:
public class Selectable<T>: ViewModelBase //ViewModelBase should Implement NotifyPropertyChanged.
{
private T _model;
public T Model
{ get { return _model; }
set
{
_model = value;
NotifyPropertyChange("Model");
}
}
public Action OnIsSelectedChanged;
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
NotifyPropertyChange("IsSelected");
if (OnIsSelectedChanged != null)
OnIsSelectedChanged();
}
}
}
了解我在IsSelected
更改后将如何使用Delegate,以便您可以在ViewModel级别处理选择更改:
public class CheckBoxValue: Selectable<string>
{
//.. no need for any special stuff here
}
public class myViewModel : ViewModelBase
{
public ObservableCollection<CheckBoxValue> CheckBoxCollection { get; set; }
public myViewModel( Some Parameters.... )
{
CheckBoxCollection = new ObservableCollection<CheckBoxValue>();
CheckBoxCollection.Add(new CheckBoxValue { Model = "CheckBox1" });
CheckBoxCollection.Add(new CheckBoxValue { Model = "CheckBox2" });
CheckBoxCollection.Add(new CheckBoxValue { Model = "CheckBox3" });
//Setting IsSelected to false is redundant because bools default to false, so I removed that.
//Calling NotifyPropertyChange in the constructor is also redundant because the object is just being constructed, therefore WPF did not even read the initial values from it yet.
//Now, here we handle the Selection change:
foreach (var item in CheckBoxCollection)
item.OnIsSelectedChanged = OnCheckBoxSelectionChanged;
}
private void OnCheckBoxSelectionChanged()
{
//... etc
}
XAML:
<!-- Two way binding to the ItemsSource property is redundant, it doesn't make sense. -->
<ItemsControl ItemsSource="{Binding Path=CheckBoxCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- CheckBox.IsChecked BindsToWayByDefault, so it is also redundant
See http://msdn.microsoft.com/en-us/library/system.windows.frameworkpropertymetadata.bindstwowaybydefault(v=vs.110).aspx -->
<!-- Also see how I'm adding content to the CheckBox here -->
<CheckBox Content="{Binding Model}"
IsChecked="{Binding Path=IsSelected}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
}
答案 1 :(得分:0)
我可能改变了太多但这可能是更简单的方法。
<StackPanel>
<CheckBox IsChecked="{Binding Path=CheckBoxValue1, Mode=TwoWay}" />
<CheckBox IsChecked="{Binding Path=CheckBoxValue2, Mode=TwoWay}" />
<CheckBox IsChecked="{Binding Path=CheckBoxValue3, Mode=TwoWay}" />
<TextBlock>
<TextBlock.Text>
<Binding Path="StringValue" UpdateSourceTrigger="PropertyChanged" />
</TextBlock.Text>
</TextBlock>
</StackPanel>
#region properties
string stringValue;
public StringValue
{
get {return stringValue;}
set
{
stringValue = value;
OnPropertyChanged("StringValue");
}
}
bool checkBoxValue1;
public bool CheckBoxValue1
{
get{ return checkBoxValue1; }
set
{
checkBoxValue1= value;
ChangedValue();
}
}
bool checkBoxValue2;
public bool CheckBoxValue2
{
get{ return checkBoxValue2; }
set
{
checkBoxValue2 = value;
ChangedValue();
}
}
bool checkBoxValue3;
public bool CheckBoxValue3
{
get{ return checkBoxValue3; }
set
{
checkBoxValue3 = value;
ChangedValue();
}
}
#endregion
public class myViewModel : ViewModelBase
{
public myViewModel( Some Parameters.... )
{
checkBoxValue1 = false;
checkBoxValue2 = false;
checkBoxValue3 = false;
StringValue = b;
}
public void ChangedValue()
{
if (checkBoxValue1 && checkBoxValue2 && checkBoxValue3)
{
StringValue = a
}
else
{
StringValue = b
}
}
}
对不起,这有点被抛在一起,但希望你能得到这个想法