【问题标题】:Disable Text Selection in TextBox Style禁用 TextBox 样式中的文本选择
【发布时间】: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 中定义的,我看不到我在哪里覆盖了该属性。

标签: c# wpf textbox textselection


【解决方案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个可能的问题:

    1. 您没有正确绑定文本框
    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 (但你的应用程序的其余部分也将默认设置):
    【解决方案3】:

    好吧,禁止突出显示文本的一种快速方法是添加 到 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
    猜你喜欢
    • 2012-10-26
    • 2013-01-16
    • 2017-06-10
    • 2013-07-15
    • 2017-07-11
    • 2010-11-14
    • 2018-10-09
    • 2015-08-09
    • 1970-01-01
    相关资源
    最近更新 更多