在我的主Window
我有一个MenuItem
和一个UserControl
。如果MenuItem
中的一个TextBoxes
分别为空/非空,我想禁用/启用UserControl
。
如果UserControl
名为ContactDetails
,TexBox
名为ContactNameTextBox
,请参阅MenuItem
我的xaml代码:
<MenuItem x:Name="DeleteContact"
Header="Delete Contact"
IsEnabled="{Binding ElementName=ContactDetails.ContactNameTextBox,Path=Text.Length, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
出于某种原因,MenuItem
始终保持启用状态。我错过了什么?
答案 0 :(得分:0)
你绑定到文本的长度但你需要一个从长度到bool的转换器,因为IsEnabled属性需要一个bool。
public class NumToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value!=null && value is int )
{
var val = (int)value;
return (val==0) ? false : true;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value!=null && value is bool )
{
var val = (bool)value; return val ? 1 : 0;
}
return null;
}
}
为此添加本地xmlns和资源。
xmlns:local="clr-namespace:YourNamespace"
这是对转换器类的引用。
<local:NumToBoolConverter x:Key="NumToBoolConverter"/>
在你的Binding部分添加:
Converter={StaticResource NumToBoolConverter}
这可能是您最终的MenuItem定义:
<MenuItem x:Name="DeleteContact"
Header="Delete Contact"
IsEnabled="{Binding ElementName=ContactDetails.ContactNameTextBox,
Path=Text.Length,
Converter={StaticResource NumToBoolConverter},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
答案 1 :(得分:0)
绑定存在一些问题。首先是您指定了双向绑定。这意味着您要回写文本框中的“length”属性。因为它是readonly你不能。
通常你应该得到一个错误:
TwoWay或OneWayToSource绑定无法在只读模式下运行 'System.String'类型的属性'Length'。
奇怪的是,绑定确实在那之后起作用。但这真的不是正确的方法。 .NET的神奇之处在于允许将0解释为“false”。但它不是一个安全的约束力。正如Olaru在他的回答中所说,length属性是一个整数,IsEnabled字段正在寻找一个bool。如果您想绑定到'visibility'属性怎么办?
那么处理这个问题的最佳方法是什么?转换器绝对是一种选择,在许多情况下是最佳选择。转换器的优点是它们可以在类似的情况下重复使用。我们有一个充满了我们经常使用的转换器的库。 Olaru已经描述了如何做到这一点,所以我不会重复他已经说过的话。
在某些情况下,了解不同的方式是有益的。数据触发器将允许您执行与转换器相同的操作。这是一种单向约束。这是一个例子。
<MenuItem x:Name="DeleteContact" Header="Delete Contact">
<MenuItem.Style>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="MenuItem.IsEnabled" Value="true"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=ContactNameTextBox}" Value="0">
<Setter Property="MenuItem.IsEnabled" Value="false"/>
</DataTrigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
</MenuItem>
无需代码!!
关于转换器和数据触发器的优缺点,有很多争论。但最重要的是要知道有多种方法可以做你要求的事情。