在Silverlight中,如何使IsReadOnly="True"
的TextBox不会变灰。我的应用程序的灰色效果看起来很糟糕,我想禁用它,或者改变它的外观/颜色。
答案 0 :(得分:11)
Silverlight 2中有几个选项,最简单的方法是使用TextBlock,因为它只是readonly。
如果你需要一个TextBox,那么你需要做的就是给它一个不起灰色效果的不同风格。
要做到这一点,打开混合。右键单击TextBox并选择Edit Control Parts(Template) - >编辑副本...无论您想要什么,都可以调用新样式。
然后,您想要编辑此新样式并删除名为“ReadOnlyVisualElement”的边框,并删除改变该边框的不透明度属性的故事板。
希望这有帮助。
添加了样式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 :(得分:10)
似乎没有任何东西在xaml中工作(像往常一样),所以我提出的最佳解决方案就是在没有IsReadOnly属性的情况下自己创建一个文本框。
public class ReadOnlyTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
e.Handled = true;
base.OnKeyDown(e);
}
}
答案 2 :(得分: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.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>
您甚至可以删除已禁用的状态。
答案 3 :(得分:2)
这是@Struan答案的增强版。
如果您想要一个只读文本框,我假设您要允许Select all
和Copy
。您需要处理Ctrl+A
和Ctrl+C
等按键。
免责声明:这不是一套完整的密钥 - 您可能需要添加更多密钥,但至少可以进行复制。
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>
答案 4 :(得分:0)
我发现@ Simon_Weaver的解决方案最容易实现。我做的唯一改变是检查Key.Tab以及左/右/上/下,以便我可以跳出字段。我创建了类 ReadOnlyTextBox 并复制了上面的代码。然后我添加了Key.Tab的检查并编译。接下来,我从
更改了我的Xaml标签<TextBox ... IsEnabled="False" />
到
<MyNameSpace:ReadOnlyTextBox ... Background="LightGray" />
(删除IsEnabled引用并添加背景颜色)。它的外观和工作完全符合我的预期。
谢谢西蒙。
答案 5 :(得分: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属性。
答案 6 :(得分:0)
在按钮的定义/行为/外观发生变化之前,另一个更优雅的解决方案是简单地将TextBox更改为Button。将“文本”属性更改为“内容”属性以设置显示的文本,删除“IsReadOnly”设置,您将获得所需的效果,我相信(类似于文本框的平面控件支持文本和所有边框,背景,没有不透明度变化的TextBox的前景属性[灰化]和定义新样式的麻烦)。
当用户尝试与此控件进行交互时,它的功能会在click事件中发生更改,但如果没有与该按钮关联的事件处理程序,则不会对您的界面产生任何影响。事实上,我认为默认按钮行为会使效果看起来有点“酷”。