CheckBox
、ComboBox
和 Button
的 IsEnabled
属性设置为 False
。然而,TextBox
应该允许复制它们的文本,因此不应被禁用,但只能是只读状态。
我尝试遍历 LogicalTree
,但一些自建用户控件没有任何禁用属性,但是该用户控件内包含的控件只有按钮和文本框。这就是我尝试对所有可改变的元素(CheckBox
、ComboBox
、Button
和 TextBox
)应用样式,但它不起作用的原因。
在用户控件的 Ressources
部分中,我定义了一些样式:
<Style TargetType="Control" x:Key="disabledStyle">
<Setter Property="IsEnabled" Value="False" />
</Style>
<Style TargetType="TextBox" x:Key="readOnlyStyle">
<Setter Property="IsReadOnly" Value="True" />
</Style>
在CodeBehind中,检查条件后,我尝试了以下操作:
# windowOwner is the root window containing this usercontrol
for control in [Button, ComboBox, CheckBox]:
if self.windowOwner.Resources.Contains(control):
self.windowOwner.Resources.Remove(control)
self.windowOwner.Resources.Add(control, self.Resources['disabledStyle'])
if self.windowOwner.Resources.Contains(TextBox):
self.windowOwner.Resources.Remove(TextBox)
self.windowOwner.Resources.Add(TextBox, self.Resources['readOnlyStyle'])
但是什么都没有发生。我做错了什么吗?我应该使用不同的方法吗?
=编辑1==================================================================
我现在尝试了以下XAML代码:
<Style x:Key="disabledStyle">
<!--<Setter Property="Button.IsEnabled" Value="False" />
<Setter Property="CheckBox.IsEnabled" Value="False" />-->
<Setter Property="ComboBox.IsEnabled" Value="False" />
<Setter Property="TextBox.IsReadOnly" Value="True" />
</Style>
CodeBehind:
self.windowOwner.Style = self.Resources['disabledStyle']
令人惊讶的是,即使只为ComboBox
设置了IsEnabled
属性,所有内容都会被禁用。如果我只设置TextBox.IsReadOnly
属性,则不会发生任何事情。有人能解释一下吗?
=编辑2==================================================================
我现在也尝试使用转换器:
(XAML)
<Style TargetType="Control" x:Key="disabledStyle">
<Setter Property="IsEnabled" Value="False" />
<!--<Setter Property="Button.IsEnabled" Value="False" />
<Setter Property="CheckBox.IsEnabled" Value="False" />
<Setter Property="ComboBox.IsEnabled" Value="False" /> -->
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource typeConverter}}" Value="True">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="TextBox.IsReadOnly" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
(转换器)
public class TypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool res = value.GetType() == typeof(TextBox);
return res;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{ // Don't need any convert back
return null;
}
}
但是,再次强调,所有内容都被禁用了(或者如果你使用注释掉的变体,则什么也不会发生)。
我通过遍历可视树使其正常工作:
visited = set()
def disableControls(control):
visited.add(control)
try:
for childNumber in xrange(VisualTreeHelper.GetChildrenCount(control)):
child = VisualTreeHelper.GetChild(control, childNumber)
if hasattr(child, 'Content') and child.Content not in visited:
disableControls(child.Content)
if type(child) in [Button, ComboBox, CheckBox]:
child.IsEnabled = False
elif type(child) == TextBox:
child.IsReadOnly = True
elif child not in visited:
disableControls(child)
except:
pass
disableControls(self.windowOwner)
但我也希望能够稍后将更改重置为原始状态。这意味着我必须保存所有更改,这使得它比应该的要复杂得多。我没有更好的想法。