2011-03-10 124 views
1

我幾次閱讀Style s,Style.Trigger s和Property-Setters上的描述,但是我仍然會,如果樣式應用或者不是完全隨機的。WPF樣式屬性設置器不適用於所有類型

在下面的例子中,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> 

我想這有做一些與PathCanvas內嵌套,但是再一次,必須有一種方法來設置控件的子元素。

我不得不承認,來自HTML/CSS,我發現WPF樣式不必要的困難!任何觀點或解釋歡迎!

感謝, 湯姆

回答

2

您不能以這種方式訪問​​UserControl的可視元素。樣式只能在UserControl上設置屬性。因此,您的第一個setter(「Path.Stroke」)將在名爲Path的UserControl上查找屬性,然後將其設置爲Stroke。它不會將其應用於UserControl中的所有路徑或您已在下面定義的路徑。

Canvas的背景沒有設置。 UserControl的背景被設置,畫布將繼續沒有背景。 Setter在UserControl上工作的原因是因爲Canvas.BackgroundPropertyUserControl.BackgroundProperty是相同的依賴項屬性(即使它們是不同的所有者)。

我建議在您的UserControl上公開依賴項屬性,它們由您的樣式更改並且由您的元素綁定。像這樣的東西(它重用了背景/前景屬性):

<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> 
+0

優秀的答案。不是我所期望的,但至少我現在明白了我應該如何處理這類問題。 – pixtur 2011-03-10 13:12:26

0

如果定義了Style爲UserControl上一個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> 

+0

啊,我已經玩過了。但是沒有辦法直接從樣式定義中訪問子元素。將每個單獨的UiElement-Markup交叉引用到Style-Markup似乎是它們之間不必要的複雜綁定。 – pixtur 2011-03-10 09:51:54

0

雖然不是通過風格,但這是一個解決方法,我用我的應用程序來實現這件事。

* 視覺兒童查找*

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

現在你有控制,你可以用它在代碼後面玩耍。我同意我們應該尋找一些東西來實現這一點,使用XAML中的STYLE

+0

啊,很酷。現在,我使用屬性更改處理程序後面的代碼來完成樣式。但我努力避免這樣做,以實現乾淨的代碼/用戶界面/風格分離。 – pixtur 2011-03-10 13:11:08

+0

好吧!不錯.. – Rohit 2011-03-10 16:29:06

相關問題