禁用 TextBox 样式中的文本选择
Posted
技术标签:
【中文标题】禁用 TextBox 样式中的文本选择【英文标题】:Disable Text Selection in TextBox Style 【发布时间】:2012-04-29 05:17:46 【问题描述】:我想最好使用样式禁用文本框中的文本选择。原因是我有一种风格,它使文本框看起来像一个文本块,直到满足某个标准(IsRenaming)。这些是树视图的节点,所以我不希望用户能够选择文本。这是样式:
<Style x:Key="TextBlockStyleForTextBox" TargetType="x:Type TextBox" BasedOn="StaticResource x:Type TextBox">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
</Style>
<Style x:Key="RenamingTextBox" TargetType="x:Type TextBox" BasedOn="StaticResource TextBlockStyleForTextBox">
<Setter Property="Cursor" Value="Arrow"/>
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Style.Triggers>
<DataTrigger Binding="Binding IsRenaming" Value="true">
<DataTrigger.Setters>
<Setter Property="TextBox.IsReadOnly" Value="False" />
<Setter Property="Cursor" Value="IBeam" />
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Color="DynamicResource WhiteColor"/>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="2" />
<Setter Property="FocusManager.FocusedElement" Value="Binding RelativeSource=RelativeSource Self"/>
<Setter Property="behaviors:TextBoxBehavior.SelectAll" Value="True"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
我认为我不会在任何地方覆盖 IsReadOnly。这是我的文本框定义:
<DataTemplate x:Key="MyTemplate" >
<TextBox Text="Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True"
Tag="Binding DataContext, RelativeSource=RelativeSource AncestorType=TreeView"
Style="StaticResource RenamingTextBox">
...等
【问题讨论】:
那么什么不起作用?看起来绑定应该触发 IsReadOnly 就好了 您的 TextBox 定义是什么样的?您是否在那里覆盖 IsReadOnly 属性(或您的样式中的任何其他属性)? @WonkotheSane - 我在上面添加了我对 TextBox 的定义。它们是在 HierarchicalDataTemplates 中定义的,我看不到我在哪里覆盖了该属性。 【参考方案1】:这又快又脏,但这是我们在另一个答案中的对话的一个很好的开始/示例,您可以对样式进行额外的调整,但它完全有效(刚刚测试过)
<Style x:Key="RenamingTextBox" TargetType="x:Type TextBox">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type TextBox">
<Grid>
<TextBlock x:Name="block" Visibility="Visible" Text="TemplateBinding Text" Margin="1.5"/>
<TextBox x:Name="box" Visibility="Collapsed" Text="TemplateBinding Text"/>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="Binding IsRenaming" Value="true">
<DataTrigger.Setters>
<Setter TargetName="block" Property="TextBox.Visibility" Value="Collapsed" />
<Setter TargetName="box" Property="TextBox.Visibility" Value="Visible" />
</DataTrigger.Setters>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
【讨论】:
【参考方案2】:您的样式运行良好,因为我刚刚对它们进行了测试! 3个可能的问题:
-
您没有正确绑定文本框
你没有指定你的风格
IsRemaining 没有提高属性的变化
这是我的测试
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="500" Width="600"
x:Name="wnd">
<Window.Resources>
...I put your styles in there..
</Windows.Resources>
<StackPanel>
<TextBox DataContext="Binding ViewModel, ElementName=wnd" Style="StaticResource RenamingTextBox" >tata</TextBox>
<Button Command="Binding ViewModel.SomeCommand, ElementName=wnd">change read only</Button>
</StackPanel>
背后的代码 (.xaml.cs)
public partial class MainWindow : Window
public ViewModel ViewModel get; set;
public MainWindow()
ViewModel = new ViewModel();
InitializeComponent();
public class ViewModel : INotifyPropertyChanged
private DelegateCommand _someCmd;
private bool _isRenaming;
public DelegateCommand SomeCommand
get
return _someCmd ?? (_someCmd = new DelegateCommand(() =>
IsRenaming = true;
));
public bool IsRenaming
get return _isRenaming;
set
_isRenaming = value;
RaisePropertyChanged("IsRenaming");
【讨论】:
该风格的其他部分效果很好。当 IsRenaming 为真时,它使它看起来像一个文本框并允许编辑。通常它不允许编辑,但仍然允许选择。我不希望用户能够选择文本(使其难以阅读)。 好吧,我想你可能想看看切换 textBlock(用于只读行为)与 TextBox 进行编辑。 你可以设置系统键颜色 SystemColors.HighlightBrushKey (但你的应用程序的其余部分也将默认设置):好吧,禁止突出显示文本的一种快速方法是添加 到 IsEnabled 的样式切换。否则,您可能希望使用 StackPanel 覆盖 TextBox 的模板,该模板可以切换 TextBox 和 TexBlock - 超级容易做到,并且到处都是大量样本,即使在堆栈溢出时也是如此。 这是您使用 IsEnabled 修改后的样式..
<Style x:Key="TextBlockStyleForTextBox" TargetType="x:Type TextBox" BasedOn="StaticResource x:Type TextBox">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="IsEnabled" Value="False"/>
</Style>
<Style x:Key="RenamingTextBox" TargetType="x:Type TextBox" BasedOn="StaticResource TextBlockStyleForTextBox">
<Setter Property="Cursor" Value="Arrow"/>
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Style.Triggers>
<DataTrigger Binding="Binding IsRenaming" Value="true">
<DataTrigger.Setters>
<Setter Property="TextBox.IsReadOnly" Value="False" />
<Setter Property="IsEnabled" Value="True"/>
<Setter Property="Cursor" Value="IBeam" />
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Color="DynamicResource WhiteColor"/>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="2" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
【讨论】:
设置 IsEnabled 的唯一问题是它会使文本和背景变灰,使其看起来被禁用。我希望它看起来已启用...只是不可选择/可突出显示:) 文本块和文本框之间切换的示例?或者您可以将链接添加到示例以供将来参考,以便其他人不需要搜索? 当然,给我一点,我要么找到它,要么快速给你打出来 @KrisTrip,好的,刚刚输入了一些东西......似乎比查找要快,但我发誓那里有一些东西的语气,我今天没有我的 google foo以上是关于禁用 TextBox 样式中的文本选择的主要内容,如果未能解决你的问题,请参考以下文章
将 ErrorTemplate 添加到 WPF 用户控件会禁用 TextBox 输入
WPF 处理textbox的样式问题,点击获得焦点背景颜色变化,当点击窗体其他地方(非控件),textbox自动