C# 防止只读文本框在 Silverlight 中变灰

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1041512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:47:44  来源:igfitidea点击:

Prevent a readonly textbox from being grayed out in Silverlight

c#.netsilverlightxaml

提问by Struan

In Silverlight, How do I make a TextBox with IsReadOnly="True"not become grayed out. The gray effect looks horrible with my app and I would like to disable it, or change its appearance/color.

在 Silverlight 中,如何制作一个IsReadOnly="True"不会变灰的文本框。我的应用程序的灰色效果看起来很糟糕,我想禁用它,或更改其外观/颜色。

采纳答案by Graeme Bradbury

There are a couple of options in Silverlight 2, the simplest would be to use a TextBlock since that's only ever readonly.

Silverlight 2 中有几个选项,最简单的是使用 TextBlock,因为它只是只读的。

If you need a TextBox then what you need to do is give it a different style that doesn't do the grey affect.

如果你需要一个 TextBox,那么你需要做的是给它一个不同的样式,不会产生灰色影响。

To do this open up blend. right click on your TextBox and select Edit Control Parts (Template) -> Edit a Copy... Call the new style whatever you want.

要做到这一点,打开混合。右键单击您的 TextBox 并选择 Edit Control Parts (Template) -> Edit a Copy... 随意调用新样式。

You then want to edit this new style and delete the border called "ReadOnlyVisualElement" and delete the storyboard that alters the opacity property of that border.

然后,您要编辑此新样式并删除名为“ReadOnlyVisualElement”的边框,并删除更改该边框不透明度属性的故事板。

Hope this helps.

希望这可以帮助。

Added Style XAML

添加样式 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>

I would get the preview of Blend, coding the above by hand would be a large amount of unnecessary work.

我会得到 Blend 的预览,手工编写上面的代码将是大量不必要的工作。

回答by Struan

Nothing seems to work in the xaml (as usual), so the best solution I've come up with is make a textbox readonly myself without the IsReadOnly property.

xaml 中似乎没有任何工作(像往常一样),所以我想出的最好的解决方案是在没有 IsReadOnly 属性的情况下让我自己只读一个文本框。

public class ReadOnlyTextBox : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        e.Handled = true;
        base.OnKeyDown(e);
    }
}

回答by Simon_Weaver

Here's an enhanced version of @Struan's answer.

这是@Struan 答案的增强版。

I assume you want to allow Select alland Copyif you're wanting a read only textbox. You need to handle keypresses such as Ctrl+Aand Ctrl+C.

我假设你想允许Select allCopy如果你想要一个只读的文本框。您需要处理诸如Ctrl+A和 之类的按键Ctrl+C

Disclaimer:this is not a fully complete set of keys - you may need to add more, but this will allow for copy at least.

免责声明:这不是一套完整的密钥 - 您可能需要添加更多,但这至少允许复制。

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);
    }
}

And here's a simple Style I'm using that indicates to the user that the item is selectable, but is smaller than a typical textbox.

这是我正在使用的一个简单样式,它向用户表明该项目是可选的,但比典型的文本框小。

<Style TargetType="my:ReadOnlyTextBox">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="3,0,3,0"/>
    <Setter Property="Background" Value="Transparent"/>
</Style>

回答by Chris S

If you just want an equivalent of a block of text in HTML, that can be selected (which for some reason even Silverlight 4 is missing) you can shorten Graeme's answer slightly:

如果你只想要一个相当于 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.TargetProperty="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>

You may even be able to remove the disabled states.

您甚至可以删除禁用状态。

回答by Tom Faust

I found @Simon_Weaver's solution the easiest to implement. The only change I made was to check for Key.Tab along with left/right/up/down so that I could tab out of the field. I created the class ReadOnlyTextBoxand copied the code above. Then I added the check for Key.Tab and compiled. Next I changed my Xaml tag from

我发现@Simon_Weaver 的解决方案最容易实现。我所做的唯一更改是检查 Key.Tab 以及左/右/上/下,以便我可以跳出该字段。我创建了类ReadOnlyTextBox并复制了上面的代码。然后我添加了对 Key.Tab 的检查并编译。接下来我改变了我的 Xaml 标签

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

to

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

(removing the IsEnabled reference and adding the background color). It looks and works exactly as I expected.

(删除 IsEnabled 引用并添加背景颜色)。它的外观和工作方式完全符合我的预期。

Thanks Simon.

谢谢西蒙。

回答by tech

I wanted to reduce the style to bare bone, and tested this with silverlight 4.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>

It is almost a cheat, like saying:Hey silverligh, this textbox is a textblock!You should eventually add something in the TextBlock tag, to better reflect other TextBox properties.

这几乎是一种欺骗,就像说:Hey silverligh, this textbox is a textblock!您最终应该在 TextBlock 标记中添加一些内容,以更好地反映其他 TextBox 属性。

回答by Epsilon3

Until the definition/behavior/appearance of a button changes, another more elegant solution is to simply change your TextBox to a Button. Change the 'Text' property to a 'Content' property to set the text displayed, remove the 'IsReadOnly' setting and you will have the effect you desire, I believe (a flat text-box-like control that supports text and all the border, background, foreground properties of a TextBox without the opacity change [graying-out] and the hassle of defining a new style).

在按钮的定义/行为/外观发生变化之前,另一个更优雅的解决方案是简单地将您的 TextBox 更改为一个按钮。将“Text”属性更改为“Content”属性以设置显示的文本,删除“IsReadOnly”设置,您将获得所需的效果,我相信(一个类似文本框的平面控件,支持文本和所有文本框的边框、背景、前景属性没有不透明度变化 [变灰] 和定义新样式的麻烦)。

When a user attempts to interact with this control, it's features change on the click event, but without an event handler associated with the button, there will be no impact to your interface. In fact, I think the default button behavior makes the effect appear kind of "cool".

当用户尝试与此控件交互时,它的功能会在单击事件上发生变化,但如果没有与按钮关联的事件处理程序,则不会对您的界面产生影响。事实上,我认为默认按钮行为使效果看起来有点“酷”。