У меня есть приложение с несколькими пользовательскими элементами управления, которые используются в определенных окнах. Одно из этих usercontrols определяет, должны ли все другие пользовательские элементы управления в этом окне разрешать редактирование, поэтому для свойства IsEnabled
для False
для всех CheckBox
es, ComboBox
es и Button
s. Тем не менее, TextBox
es должны позволять копировать текст, поэтому его нельзя отключать, но только для чтения.
Я пробовал перемещаться по LogicalTree
, но у некоторого автономного пользователя usercontrol нет никакого свойства, чтобы отключить их, но элементы управления, содержащиеся в этом usercontrol, являются только кнопками и текстовыми полями. Поэтому я попытался применить стиль ко всем изменяемым элементам (CheckBox
, ComboBox
, Button
и TextBox
), но это не сработает.
В разделе usercontrol 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'])
Но ничего не произошло. Что я делаю не так? Должен ли я делать это по-другому?
= EDIT 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']
Удивительно, хотя свойство IsEnabled
установлено только для ComboBox
, все отключено. И если я устанавливаю только свойство TextBox.IsReadOnly
, ничего не происходит. Может кто-нибудь объяснить это?
= EDIT 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)
Но я также хотел бы иметь возможность позже reset внести изменения в исходное состояние. И это означало бы, что я должен был бы сэкономить все изменения, что делает это намного сложнее, чем должно быть. У меня нет идей.