Вопрос по c#, .net, xaml, silverlight – Предотвратите недоступность текстового поля только для чтения в Silverlight

11

В Silverlight, Как сделать TextBox сIsReadOnly="True" не становится серым Эффект серого выглядит ужасно с моим приложением, и я хотел бы отключить его или изменить его внешний вид / цвет.

Ваш Ответ

7   ответов
3

Если вы просто хотите выбрать эквивалент блока текста в HTML, который можно выбрать (который по какой-то причине отсутствует даже в Silverlight 4), вы можете немного сократить ответ Graeme:

<Style x:Key="ReadOnlyStyle" TargetType="TextBox">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Background" Value="#FFFFFFFF"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Grid x:Name="RootElement">
                    <vsm:VisualStateManager.VisualStateGroups>
                        <vsm:VisualStateGroup x:Name="CommonStates">
                            <vsm:VisualState x:Name="Normal"/>
                            <vsm:VisualState x:Name="MouseOver"/>
                            <vsm:VisualState x:Name="Disabled" />
                            <vsm:VisualState x:Name="ReadOnly"/>
                        </vsm:VisualStateGroup>
                        <vsm:VisualStateGroup x:Name="FocusStates">
                            <vsm:VisualState x:Name="Focused">
                   ,             <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
                                        <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                            <vsm:VisualState x:Name="Unfocused">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetPr,operty="Opacity">
                                        <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                        </vsm:VisualStateGroup>
                    </vsm:VisualStateManager.VisualStateGroups>
                    <Border x:Name="Border" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1">
                        <Grid>
                            <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1">
                                <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/>
                            </Border>
                        </Grid>
                    </Border>
                    <Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Opacity="0" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}"/>
                    <Border x:Name="FocusVisualElement" Margin="1" IsHitTestVisible="False" Opacity="0" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Возможно, вы даже сможете удалить отключенные состояния.

0

Я нашел решение @ Simon_Weaver наиболее простым для реализации. Единственное изменение, которое я сделал, было проверить Key.Tab вместе с left / right / up / down, чтобы я мог перемещаться из поля. Я создал классReadOnlyTextBox и скопировал код выше. Затем я добавил проверку для Key.Tab и скомпилировал. Затем я изменил свой тег Xaml с

<TextBox ... IsEnabled="False" />

в

<MyNameSpace:ReadOnlyTextBox ... Background="LightGray" />

(удаление ссылки IsEnabled и добавление цвета фона). Это выглядит и работает именно так, как я ожидал.

Спасибо Саймон.

2

Вот улучшенная версия ответа @ Struan.

Я полагаю, вы хотите разрешитьSelect all а такжеCopy если вы хотите текстовое поле только для чтения. Вы должны обрабатывать нажатия клавиш, такие какCtrl+A а такжеCtrl+C.

Disclaimer: это не полный набор ключей - вам может понадобиться добавить еще, но это позволит, по крайней мере, копировать.

public class ReadOnlyTextBox : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down)
        {
            base.OnKeyDown(e);
            return;
        }

        if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control ||
            (Keyboard.Modifiers & ModifierKeys.Apple) == ModifierKeys.Apple)
        {
            if (e.Key == Key.A || e.Key == Key.C)
            {
                // allow select all and copy!
                base.OnKeyDown(e);
                return;
            }
        }

        e.Handled = true;
        base.OnKeyDown(e);
    }
}

И здесь используется простой стиль, который я использую, который указывает пользователю, что элемент можно выбрать, но он меньше, чем типичное текстовое поле.

<Style TargetType="my:ReadOnlyTextBox">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="3,0,3,0"/>
    <Setter Property="Background" Value="Transparent"/>
</Style>
хмм забой еще работает :-(
0

До тех пор, пока определение / поведение / внешний вид кнопки не изменится, еще одно более элегантное решение - просто изменить текстовый блок на кнопку. Измените «текст» свойство к «контенту»; свойство для установки отображаемого текста, удалите «IsReadOnly» Я полагаю, что вы получите желаемый эффект (плоский элемент управления в виде текстового поля, поддерживающий текст и все свойства границ, фона, переднего плана TextBox без изменения непрозрачности [затенение] и трудности определения новый стиль).

Когда пользователь пытается взаимодействовать с этим элементом управления, его функции изменяются в событии click, но без обработчика события, связанного с кнопкой, ваш интерфейс не будет влиять. На самом деле, я думаю, что поведение кнопки по умолчанию делает эффект вроде «крутым».

О, я должен добавить, что вы должны быть осторожны при доступе к элементу управления как дочернему компоненту, чтобы убедиться, что вы вводите его в Button, а не в TextBox, но я предполагаю, что большинство разработчиков, задающих этот вопрос, поймут это.
0

Я хотел уменьшить стиль до голой кости и протестировал это с помощью Silverlight 4.0:

<Style x:Key="ReadOnlyStyle" TargetType="TextBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <TextBlock Text="{TemplateBinding Text}"  TextAlignment="{TemplateBinding TextAlignment}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Это почти чит, как сказать:Hey silverligh, this textbox is a textblock! В конечном итоге вы должны добавить что-то в тег TextBlock, чтобы лучше отражать другие свойства TextBox.

10

что ничего не работает в xaml (как обычно), поэтому лучшее решение, которое я нашел, - это сделать текстовое поле самостоятельно только для чтения без свойства IsReadOnly.

public class ReadOnlyTextBox : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        e.Handled = true;
        base.OnKeyDown(e);
    }
}
Спасибо, Струан, - я закончил этот путь. Я изменил ваш код, установив e.Handled = true, только если клавиша Ctrl не нажата, а клавиша не является клавишей со стрелкой или клавишей табуляции. Таким образом, люди все еще могут перемещаться по элементу управления и нажимать Ctrl + C для копирования.
+1 для "как обычно"
Это помогло с проблемой, с которой я пытался создать комбобокс для чтения. В моем случае мне также пришлось обрабатывать OnKeyUp с тем же кодом, чтобы остановить запуск обработчика событий KeyUp.
Еще +1 для "как обычно". Одна из проблем, связанных с этим подходом, заключается в том, что вы получаете границу и курсор при нажатии на текстовое поле.
11

В Silverlight 2 есть несколько вариантов, простейшим было бы использование TextBlock, поскольку он только для чтения.

Если вам нужен TextBox, то вам нужно придать ему другой стиль, который не влияет на серый цвет.

Для этого откройте смесь. щелкните правой кнопкой мыши на TextBox и выберите «Редактировать элементы управления (шаблон)» - & gt; Редактировать копию ... Называйте новый стиль как хотите.

Затем вы хотите отредактировать этот новый стиль и удалить границу & quot; ReadOnlyVisualElement & quot; и удалите раскадровку, которая изменяет свойство непрозрачности этой границы.

Надеюсь это поможет.

Добавлен стиль XAML

    <Style x:Key="ReadOnlyStyle" TargetType="TextBox">
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Background" Value="#FFFFFFFF"/>
        <Setter Property="Foreground" Value="#FF000000"/>
        <Setter Property="Padding" Value="2"/>
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFA3AEB9" Offset="0"/>
                    <GradientStop Color="#FF8399A9" Offset="0.375"/>
                    <GradientStop Color="#FF718597" Offset="0.375"/>
                    <GradientStop Color="#FF617584" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TextBox">
                    <Grid x:Name="RootElement">
                        <vsm:VisualStateManager.VisualStateGroups>
                            <vsm:VisualStateGroup x:Name="CommonStates">
                                <vsm:VisualState x:Name="Normal"/>
                                <vsm:VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
                                            <SplineColorKeyFrame KeyTime="0" Value="#FF99C1E2"/>
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="ReadOnly">
                                    <Storyboard>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                            <vsm:VisualStateGroup x:Name="FocusStates">
                                <vsm:VisualState x:Name="Focused">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="Unfocused">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                            <vsm:VisualStateGroup x:Name="ValidationStates">
                                <vsm:VisualState x:Name="Valid"/>
                                <vsm:VisualState x:Name="InvalidUnfocused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="InvalidFocused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <System:Boolean>True</System:Boolean>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                        </vsm:VisualStateManager.VisualStateGroups>
                        <Border x:Name="Border" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1">
                            <Grid>
                                <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1">
                                    <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/>
                                </Border>
                            </Grid>
                        </Border>
                        <Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Opacity="0" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}"/>
                        <Border x:Name="FocusVisualElement" Margin="1" IsHitTestVisible="False" Opacity="0" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}"/>
                        <Border x:Name="ValidationErrorElement" Visibility="Collapsed" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1">
                            <ToolTipService.ToolTip>
                                <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                                    <ToolTip.Triggers>
                                        <EventTrigger RoutedEvent="Canvas.Loaded">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <System:Boolean>true</System:Boolean>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>
                                    </ToolTip.Triggers>
                                </ToolTip>
                            </ToolTipService.ToolTip>
                            <Grid Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12" Background="Transparent">
                                <Path Fill="#FFDC000C" Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"/>
                                <Path Fill="#ffffff" Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8"/>
                            </Grid>
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Я бы получил предварительный просмотр Blend, кодирование вышеперечисленного вручную было бы большим количеством ненужной работы.

+1 за ВАМ ДОЛЖЕН БЫТЬ МЕНЯ!
Я не использую TextBlock, потому что я все еще хочу иметь возможность скопировать текст из текстового поля и вставить его в другое место. У меня нет Blend (я использую Visual Web Developer 2008 Express), поэтому я не могу попробовать ваше второе предложение. Struan
5 лет спустя. все еще полезно

Похожие вопросы