我正在尝试重新设置一些ToggleButtons。显然我不能简单地将背景设置为新颜色,因为有一个“控制模板”提供了ToggleButton的视觉行为。
所以我需要做的是在XAML中为ToggleButton指定一个替换“ControlTemplate”,它提供不同的视觉行为,超出简单的背景颜色。
的 Q1 即可。它是否正确?
我想从ToggleButton的“默认”控制模板开始,我抓住from here,然后修改它。实际上这是Silverlight的默认ControlTemplate,我想,我没有使用Silverlight,我正在使用WPF。但是...... The corresponding doc page for WPF不包含默认controltemplate的规范。它提供了“a”ControlTemplate,这不是我想要的 的 Q2 即可。我不确定我使用Silverlight中的东西是否重要。是吗?
在Silverlight示例中,应用于VisualStateManager的vsm的XML名称空间前缀。显然xml命名空间是
xmlns:vsm = "clr-namespace:System.Windows;assembly=System.Windows"
...但在其他地方我读到这个XML命名空间“不再是必需的”。
这一切都非常令人困惑。
在Googlespace中,there are references to something called "The WPF toolkit"之前我曾在WPF V4发布之前接触过{ - 3}}。我猜测一些WPF工具包的东西被卷入了WPF for .NET v4.0,这就是为什么我不再需要指定WPF工具包了。
的 Q3 即可。如果有人能证实这种理解,我会很感激。
好的,现在从ToggleButton的“默认”ControlTemplate开始,我的第一步是编译它,然后再进行任何更改。它没有编译,失败了
c:\ dev ... \ ToggleButtonStyle1.xaml(23,14):错误MC3074:XML名称空间“I used it for an autocomplete textbox”中不存在标记“VisualStateManager.VisualStateGroups”。第23行第14位。
足够清楚。然后我 查看了在XAML中指定VisualStateManager的文档。令人困惑的是,它指定了两个xml命名空间,其中一个是我实际使用的命名空间。
Q4 嗯,我应该使用哪些?其中一个,我DID使用,它没有用。文档完全不清楚指定两个XML命名空间的含义。 (关上他们的头!)
我在项目文件中引用了PresentationFramework.dll:
<ItemGroup>
....
<Reference Include="PresentationFramework" />
</ItemGroup>
我这里没有使用Visual Studio;我正在使用文本编辑器。我想了解它是如何工作的,而不是要推动的按钮。
感谢你们提供的任何帮助。
只是一个评论 - 这一切似乎都非常复杂。我想要做的就是在ToggleButton打开时更改它的颜色。这真的不应该是这么复杂。
答案 0 :(得分:5)
您不需要为VSM指定命名空间(http://schemas.microsoft.com/winfx/2006/xaml/presentation命名空间是默认的WPF命名空间,在大多数标准.xaml中声明为xmlns =“...”) - 但是只能在视觉层次结构的某些部分使用它。
例如,当我在标准UserControl中使用VSM时,它看起来像这样:
<UserControl x:Class="Whatever"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<!-- Storyboards go here -->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>
将VSM xaml置于此级别将使您的故事板能够引用Grid中包含的任何元素。这与您正在使用的ControlTemplate中的工作方式相同。但有一点需要注意的是,在你自己的 UserControls中,你可以根据自己的喜好命名视觉状态(因为你最终会调用切换到代码中的视觉状态), 内置控件,您的视觉状态必须准确命名为控件所期望的内容。
答案 1 :(得分:0)
回答我自己的问题....
Q1 是
Q2 不 - 没关系。模板“大约”相同。
Q3 不确定
Q4 我不知道。
这里的关键是我需要指定TargetFramework = 4.0。我一直在针对v3.5进行编译,我认为VSM首先在v4.0中可用,因此这就是“在命名空间xxxxx中找不到”错误的原因。
我不需要在XAML文件中指定XMLNS。
退一步 - 回答更大的问题 - 如何让ToggleButton在郁闷时改变颜色......我试着摆弄内置的ControlTemplate,但这对我来说太复杂了。 Press和Checked等发生的动画 - 我永远无法弄清楚如何让它做我想做的事。
我将模板拆分成更多的备件,没有所有的渐变和动画,然后我添加了一些动画和触发器来完成我想要它做的事情。
视觉效果是这样的。 ON:
关闭:
我使用的XAML:
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key = "ToggleButtonStyle3"
TargetType = "ToggleButton">
<!-- This is a style (template?) for a toggle button. I wanted it to
change to a contrasty color when depressed. This took me a
loooooong time and much trial and error to figure out. The visual
effect is somewhat like the buttons in the compile output log in
Visual Studio, in which you can toggle the display of errors and
warnings.
-->
<Setter Property="Background" Value="#FFF7F0D2"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC4BC64" Offset="0"/>
<GradientStop Color="#FFADA658" Offset="0.375"/>
<GradientStop Color="#FFA19A52" Offset="0.375"/>
<GradientStop Color="#FF847E43" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid x:Name="ButtonGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="InnerRectangle" Storyboard.TargetProperty="Opacity" To="0.3"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="00:00:00"
Storyboard.TargetName="InnerRectangle"
Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
To="#FFF5BF0F"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation Duration="00:00:00"
Storyboard.TargetName="InnerRectangle"
Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
To="#FFF5D018"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name ="ButtonBorder"
CornerRadius ="1"
Background ="{TemplateBinding Background}"
BorderThickness ="{TemplateBinding BorderThickness}"
BorderBrush ="{TemplateBinding BorderBrush}">
<Border x:Name="InnerButtonBorder"
CornerRadius="1"
BorderThickness="2"
Background="#FFFAEB16">
<Rectangle x:Name="InnerRectangle" Opacity="1" Fill="#F7F0D2" />
</Border>
</Border>
<ContentPresenter
x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
TextBlock.Foreground="{TemplateBinding Foreground}"
Margin="{TemplateBinding Padding}"/>
<Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
<Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FFD1C44D" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<!-- This setter hides the desired element when the ToggleButton's initial state is checked -->
<Setter TargetName="ButtonBorder" Property="Background" Value="#FFF5D018"/>
<Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#FF000000"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="False">
<Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#78999999"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
我把它放到一个单独的文件中,称之为ToggleButtonStyle3.xaml。然后我像这样使用它:
<Window.Resources>
<ResourceDictionary>
<Style ....
</Style>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/ToggleButtonStyle3.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
....
<ToggleButton Name ="btnShowAlerts"
IsChecked ="{Binding Path=ShowAlerts, Mode=TwoWay}"
Style ="{StaticResource ToggleButtonStyle3}"
Content ="alerts"
FontSize ="9"
Padding ="8,2"
Margin ="0"
ClickMode ="Press"
/>
我不知道这是否是最好的做事方式。我知道它不符合桌面的“主题”。我知道这可能很基本。我只知道我花了很多时间来弄清楚如何获得改变颜色的ToggleButton。