如何基于条件在WPF应用中设置ContentControl内TextBox的可编辑性?
WPF ContentControl内部TextBox编辑权限按需控制方案
方案一:自定义ContentControl+依赖属性(推荐,扩展性强)
通过给自定义ContentControl添加控制单个TextBox编辑状态的依赖属性,在模板中绑定这些属性来实现按需控制。
- 定义自定义ContentControl
public class CustomTextBoxContainer : ContentControl { // 控制第一个TextBox是否可编辑 public static readonly DependencyProperty IsFirstTextBoxEditableProperty = DependencyProperty.Register("IsFirstTextBoxEditable", typeof(bool), typeof(CustomTextBoxContainer), new PropertyMetadata(false)); public bool IsFirstTextBoxEditable { get => (bool)GetValue(IsFirstTextBoxEditableProperty); set => SetValue(IsFirstTextBoxEditableProperty, value); } // 控制第二个TextBox是否可编辑 public static readonly DependencyProperty IsSecondTextBoxEditableProperty = DependencyProperty.Register("IsSecondTextBoxEditable", typeof(bool), typeof(CustomTextBoxContainer), new PropertyMetadata(false)); public bool IsSecondTextBoxEditable { get => (bool)GetValue(IsSecondTextBoxEditableProperty); set => SetValue(IsSecondTextBoxEditableProperty, value); } // 控制第三个TextBox是否可编辑 public static readonly DependencyProperty IsThirdTextBoxEditableProperty = DependencyProperty.Register("IsThirdTextBoxEditable", typeof(bool), typeof(CustomTextBoxContainer), new PropertyMetadata(false)); public bool IsThirdTextBoxEditable { get => (bool)GetValue(IsThirdTextBoxEditableProperty); set => SetValue(IsThirdTextBoxEditableProperty, value); } }
- 添加布尔反转转换器
因为IsEditable为true对应TextBox的IsReadOnly为false,需要转换器反转布尔值:
public class InverseBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return !(bool)value; } }
- 编写ContentControl模板
<Window.Resources> <local:InverseBoolConverter x:Key="InverseBoolConverter"/> <ControlTemplate x:Key="ContentControl1" TargetType="{x:Type local:CustomTextBoxContainer}"> <StackPanel> <TextBox IsReadOnly="{Binding IsFirstTextBoxEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> <TextBox IsReadOnly="{Binding IsSecondTextBoxEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> <TextBox IsReadOnly="{Binding IsThirdTextBoxEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> </StackPanel> </ControlTemplate> </Window.Resources>
- 场景使用
- 窗口1(全部不可编辑,默认属性值为false,无需额外设置):
<local:CustomTextBoxContainer DockPanel.Dock="Top" Template="{StaticResource ContentControl1}"/>
- 窗口2(第一、第三个TextBox可编辑):
<local:CustomTextBoxContainer DockPanel.Dock="Top" Template="{StaticResource ContentControl1}" IsFirstTextBoxEditable="True" IsThirdTextBoxEditable="True"/>
方案二:附加属性(无需自定义控件)
通过附加属性给原生ContentControl标记编辑权限,模板中绑定这些附加属性实现控制。
- 定义附加属性类
public static class TextBoxEditPermissions { public static readonly DependencyProperty IsFirstEditableProperty = DependencyProperty.RegisterAttached("IsFirstEditable", typeof(bool), typeof(TextBoxEditPermissions), new PropertyMetadata(false)); public static void SetIsFirstEditable(UIElement element, bool value) { element.SetValue(IsFirstEditableProperty, value); } public static bool GetIsFirstEditable(UIElement element) { return (bool)element.GetValue(IsFirstEditableProperty); } // 同理添加IsSecondEditable、IsThirdEditable附加属性 }
- 修改模板绑定附加属性
<ControlTemplate x:Key="ContentControl1" TargetType="{x:Type ContentControl}"> <StackPanel> <TextBox IsReadOnly="{Binding Path=(local:TextBoxEditPermissions.IsFirstEditable), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> <TextBox IsReadOnly="{Binding Path=(local:TextBoxEditPermissions.IsSecondEditable), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> <TextBox IsReadOnly="{Binding Path=(local:TextBoxEditPermissions.IsThirdEditable), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> </StackPanel> </ControlTemplate>
- 场景使用
- 窗口1(全部不可编辑):
<ContentControl DockPanel.Dock="Top" Template="{StaticResource ContentControl1}"/>
- 窗口2(部分可编辑):
<ContentControl DockPanel.Dock="Top" Template="{StaticResource ContentControl1}" local:TextBoxEditPermissions.IsFirstEditable="True" local:TextBoxEditPermissions.IsThirdEditable="True"/>
内容的提问来源于stack exchange,提问作者mukul nagpal
相关产品推荐
相关产品推荐

