我多次阅读了关于Style
s,Style.Trigger
和Property-Setters
的说明,但是如果这些风格的应用与否,我仍然是完全随机的。
在以下示例中,Canvas
将变为白色,但Path
根本不受影响:
<UserControl x:Class="Still.Tooll.CurveEditPoint"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Still.Tooll"
>
<UserControl.Style>
<Style>
<Style.Triggers>
<Trigger Property="local:CurveEditPoint.IsSelected" Value="true">
<Setter Property="Path.Stroke" Value="#fff"/>
<Setter Property="Canvas.Background" Value="#fff"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<Canvas>
<Path StrokeThickness="0.5" Data="M 0, 0 L 40,20"/>
</Canvas>
</UserControl>
我想这需要对Path
内Canvas
的嵌套做一些事情,但是再次,必须有一种方法来设置控件的子元素的样式。
我必须承认,来自HTML / CSS,我发现WPF样式不必要地困难!任何要点或解释都欢迎!
感谢, 汤姆
答案 0 :(得分:2)
您无法以这种方式访问UserControl的可视元素。 Style只能在UserControl上设置属性。因此,您的第一个setter(“Path.Stroke”)将在您的UserControl上查找名为Path的属性,然后设置它的Stroke。它不会将其应用于UserControl中的所有路径或您在下面定义的路径。
未设置Canvas
的背景。正在设置UserControl的背景,并且画布将继续没有背景。 setter在UserControl上工作的原因是因为Canvas.BackgroundProperty
和UserControl.BackgroundProperty
是相同的依赖属性(即使它们是不同的所有者)。
我建议在UserControl上公开依赖项属性,这些属性由Style更改并由元素绑定。这样的东西(它重用了Background / Foreground属性):
<UserControl x:Name="userControl" x:Class="Still.Tooll.CurveEditPoint"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Still.Tooll"
>
<UserControl.Style>
<Style>
<Style.Triggers>
<Trigger Property="local:CurveEditPoint.IsSelected" Value="true">
<Setter Property="Foreground" Value="#fff"/>
<Setter Property="Background" Value="#fff"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<Canvas>
<Path Stroke="{Binding Element=userControl, Path=Foreground}" StrokeThickness="0.5" Data="M 0, 0 L 40,20"/>
</Canvas>
</UserControl>
答案 1 :(得分:0)
如果您在UserControl上将Style
定义为Resource
,然后将其应用于可能有效的每个元素:
<UserControl x:Class="Still.Tooll.CurveEditPoint"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Still.Tooll"
>
<UserControl.Resources>
<Style x:Key="style">
<Style.Triggers>
<Trigger Property="local:CurveEditPoint.IsSelected" Value="true">
<Setter Property="Path.Stroke" Value="#fff"/>
<Setter Property="Canvas.Background" Value="#fff"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Canvas Style="{StaticResource style}">
<Path StrokeThickness="0.5" Data="M 0, 0 L 40,20" Style="{StaticResource style}"/>
</Canvas>
答案 2 :(得分:0)
虽然不是通过风格,但这是一个解决方法,我曾经在我的应用程序中实现这一点。
* Visual Children Finder *
/// <summary>
/// This function iterates through the visual tree and returns the child item of the type child item.
/// </summary>
/// <typeparam name="childItem"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static TChild FindVisualChild<TChild>(DependencyObject obj)
where TChild : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is TChild)
{
return (TChild)child;
}
else
{
TChild childOfChild = FindVisualChild<TChild>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
在背后的某些代码中使用它,例如 - ListBox deviceImagesListBox = UtilityFunctions.FindVisualChild<RealisticListBox>(selectedRoomListBox);
现在您已拥有控件,您可以在Code Behind中使用它。我同意我们应该在XAML中使用STYLE寻找能够实现这一点的东西