我在代码中动态创建WPF元素的背后,并为每个在我建立它Grid
行由一个CheckBox
和TextBoxes
的动态数量。所需要的相互作用如下:
TextBoxes
有0
值,设置CheckBox
IsChecked
属性true
并禁用它。TextBoxes
的一个,然后从0
改变,使CheckBox
并设置IsChecked
到false
。CheckBox
,将所有相关TextBoxes
到0
和禁用CheckBox
我能做到使用此代码的最后一个的第一部分:
Binding setScoreToZeroIfIsNormalChecked = new Binding("IsChecked");
setScoreToZeroIfIsNormalChecked.Source = this.NormalCheckBoxControl;
setScoreToZeroIfIsNormalChecked.Converter = m_NormalCheckBoxJointScoresConverter;
tempJointScoreControl.JointScoreContainer.SetBinding(ContainerBase.SingleAnswerProperty, setScoreToZeroIfIsNormalChecked);
和转换器:
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool && targetType == typeof(Answer))
{
if ((bool)value)
{
Answer answer = new Answer();
answer.Value = "0";
answer.DisplayValue = "0";
return answer;
}
else
return null;
}
else
{
return null;
}
}
然而,在试图创建另一个转换器来实现其他功能,我也陷入了转换踩着彼此的问题,因为所有的功能是根据各地的CheckBox.IsChecked
财产。
反正是有完成上述所有使用一个或两个multibinding转换器?我真的希望避免创造了一大堆事件,并维持他们为了做到这一点。
这是相对容易的。一切都应该围绕解决复选框财产器isChecked。理由很简单,这是一个双向的财产。因此,无论你可以修改它,或复选框可以修改它。
所以,你做什么,你使用MultiBinding,因为这样的:
MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = multiBindingConverter;
multiBinding.Bindings.Add(new Binding("Text") { Source = txtbox1});
multiBinding.Bindings.Add(new Binding("Text") { Source = txtbox2});
multiBinding.NotifyOnSourceUpdated = true;//this is important.
checkBox.SetBinding(CheckBox.IsCheckedProperty, multiBinding);
而在你multiBindingConverter,你将有对象[]值作为第一个参数,它需要转换成IList中,并遍历它&&做你的计算,如果你要么返回真/假。(=器isChecked true或false)
现在绑定复选框的IsEnabled到复选框财产器isChecked,并使用BooleanInverterConverter。 (如果复选框被选中,就应该被禁止,反之亦然)
最后一步是使文本框听CheckBox的实际财产器isChecked。如果这是真的,他们都应该显示为0值,否则他们可以展示他们想要的东西。
所以,做一个新的MultiBinding。
MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = textboxMultiBindingConverter;
multiBinding.Bindings.Add(new Binding("IsChecked") { Source = checkbox1});
multiBinding.Bindings.Add(new Binding("Text") { Source = textbox1});
multiBinding.NotifyOnSourceUpdated = true;//this is important.
textbox1.SetBinding(TextBox.Text, multiBinding);
在textboxMultiBindingConverter的想法是要么返回文本(值[1])如果值[0] == FALSE或 “0”,如果值[0] == TRUE。
这个问题可以很容易解决,如果你会使用MVVM。
你将不得不表示在网格行中的视图模型。这将有复选框每一个文本框财产和一个。
此外,您必须包含网格和这个视图模型将暴露行的ViewModels的集合视图一个视图模型。
该视图模型为您排:
public class AnswersViewModel : ViewModelBase // From MvvmLight
{
public bool IsAnswered
{
get { return _isAnswered; }
set
{
if(value == _isAnswered)
return;
_isAnswered = value;
if(_isAnswered)
{
Answer1 = "0";
Answer2 = "0";
}
RaisePropertyChanged("IsAnswered");
}
}
public string Answer1
{
get { return _answer1; }
set
{
if(value == _answer1)
return;
_answer1 = value;
RaisePropertyChanged("Answer1");
if(_answer1 == "0" && _answer2 == "0")
{
_isAnswered = true;
RaisePropertyChanged("IsAnswered");
}
}
}
// The implementation of Answer2 is similar to Answer1
}
该视图模型的视图:
public class FooViewModel : ViewModelBase
{
public ObservableCollection<AnswersViewModel> Answers
{
get { return _answers; }
}
}
您的视图将包含与ItemsSource="{Binding Answers}"
网格和控件模板的结合到AnswersViewModel
的性质的项目。
禁用复选框我将通过在样式扳机手柄。