Отключить выделение текста в стиле TextBox

Я хочу отключить выделение текста в текстовом поле, предпочтительно используя стиль. Причина в том, что у меня есть стиль, который делает текстовое поле похожим на текстовый блок, пока не будет выполнен определенный критерий (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}">

... и т.д


person KrisTrip    schedule 17.04.2012    source источник
comment
так что не работает? выглядит привязка должна нормально запускать IsReadOnly   -  person denis morozov    schedule 18.04.2012
comment
Как выглядит ваше определение TextBox? Вы переопределяете свойство IsReadOnly (или любое другое из вашего стиля)?   -  person Wonko the Sane    schedule 18.04.2012
comment
@WonkotheSane - я добавил свое определение TextBox выше. Они определены в HierarchicalDataTemplates, и я не вижу, где я могу переопределить это свойство.   -  person KrisTrip    schedule 18.04.2012


Ответы (3)


Это быстро и грязно, но это хорошее начало / пример из нашего разговора в другом ответе, вы можете и дополнительные настройки стиля, но это полностью работает (только что проверил)

<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>    
person denis morozov    schedule 18.04.2012

Что ж, один из быстрых способов запретить выделение текста — это добавить в ваши стили переключатель IsEnabled. В противном случае вы можете захотеть переопределить шаблон TextBox с помощью StackPanel, который переключает 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>
person denis morozov    schedule 17.04.2012
comment
Единственная проблема с настройкой IsEnabled заключается в том, что затем текст и фон становятся серыми, что делает его отключенным. Я хочу, чтобы он выглядел включенным... просто его нельзя было выбрать/подсветить :) - person KrisTrip; 18.04.2012
comment
Пример переключения между текстовым блоком и текстовым полем? Или вы можете добавить ссылку на пример для дальнейшего использования, чтобы другим не нужно было искать? - person KrisTrip; 18.04.2012
comment
конечно, дайте мне немного, я либо найду, либо быстро напечатаю это для вас - person denis morozov; 18.04.2012
comment
@KrisTrip, хорошо, только что что-то набрала... кажется быстрее, чем искать, но клянусь, там много всего, просто сегодня у меня нет google foo - person denis morozov; 18.04.2012

Ваши стили работают отлично, я их только что проверил! 3 возможные проблемы:

  1. Вы неправильно привязываете TextBox
  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");
        }
    }
      }
person denis morozov    schedule 17.04.2012
comment
Остальные части стиля работают отлично. Когда IsRenaming имеет значение true, оно выглядит как текстовое поле и позволяет редактировать. Обычно он не позволяет редактировать, но все же позволяет выбирать. Я не хочу, чтобы пользователи могли выбирать текст (это затрудняет чтение). - person KrisTrip; 18.04.2012
comment
ну, я думаю, вы, возможно, захотите изучить переключение textBlock (для поведения только для чтения) против TextBox для редактирования. - person denis morozov; 18.04.2012
comment
вы можете установить цвет системного ключа SystemColors.HighlightBrushKey (но тогда остальная часть вашего приложения тоже будет по умолчанию): ‹Style.Resources› ‹SolidColorBrush x:Key={x:Static SystemColors.HighlightBrushKey} Color=LightGreen/› ‹ /Стиль.Ресурсы› - person denis morozov; 18.04.2012