2015-05-13 194 views
1

我試圖設置來自XAML的同一個usercontrol的幾個實例的fill屬性,以便區分它們。我在控件的C#代碼隱藏中使用依賴屬性,並在實例化控件時引用XAML中的依賴屬性。這裏是什麼,我已經試過一個簡單的例子,用戶控制的第一XAML:如何從XAML設置WPF usercontrol屬性?

<UserControl x:Class="RectangleFillUserControlTest.RectangleFillTest" 
      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" 
      mc:Ignorable="d" 
      d:DesignHeight="50" d:DesignWidth="150"> 
    <Grid> 
     <Rectangle x:Name="rect" HorizontalAlignment="Left" Height="50" Stroke="Black" VerticalAlignment="Top" Width="150"/> 
    </Grid> 
</UserControl> 

現在隱藏代碼:

namespace RectangleFillUserControlTest 
{ 
    public partial class RectangleFillTest : UserControl 
    { 
     SolidColorBrush fillBrush; 

     public static readonly DependencyProperty FillColourProperty = DependencyProperty.Register 
      ("FillColour", typeof(string), typeof(RectangleFillTest), new PropertyMetadata(string.Empty)); 

     public string FillColour 
     { 
      get { return (string)GetValue(FillColourProperty); } 

      set 
      { 
       SetValue(FillColourProperty, value); 
       if (value == "red") fillBrush = new SolidColorBrush(Colors.Red); 
       else fillBrush = new SolidColorBrush(Colors.Green); 
       rect.Fill = fillBrush; 
      } 
     } 

     public RectangleFillTest() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

我實例在主窗口的控制,並嘗試設置填充顏​​色爲紅色:

<Window x:Class="RectangleFillUserControlTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:RectangleFillUserControlTest" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid Background="#FF1D2CC3"> 
     <local:RectangleFillTest FillColour="red"/> 
    </Grid> 
</Window> 

但即使在運行項目時,矩形仍未填充。任何人都可以幫忙嗎?

乾杯,

回答

4

我將解釋爲什麼不工作以及如何解決。

1.-依賴屬性僅在usercontrol在可視樹中具有該依賴屬性時調用。

如果你想在這樣做,你需要添加例如:

new PropertyMetadata(string.Empty, ValueChanged)); 

有更改值:

public static readonly DependencyProperty FillColourProperty = DependencyProperty.Register 
     ("FillColour", typeof(string), typeof(RectangleFillTest), new PropertyMetadata(string.Empty, ValueChanged)); 

    private static void ValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as RectangleFillTest; 
     var fillBrush = new SolidColorBrush(); 
     if (control.FillColour == "red") 
      fillBrush = new SolidColorBrush(Colors.Red); 
     else 
      fillBrush = new SolidColorBrush(Colors.Green); 
     control.rect.Fill = fillBrush; 
    } 

    public string FillColour 
    { 
     get 
     { 
      return (string)GetValue(FillColourProperty); 
     } 

     set 
     { 
      SetValue(FillColourProperty, value); 

     } 
    } 

這是很清楚你的邏輯,萬一你需要一個更通用的代碼來處理任何顏色等,只需要將屬性綁定到矩形上即可。

+0

一直在尋找了幾個小時終於這樣做的伎倆在我之後。非常感謝您指出ValueChanged回調! – jettatore

0

您需要將依賴項屬性綁定到你的矩形在你的用戶控件的XAML Fill屬性。你會有這樣的東西:

<Rectangle x:Name="rect" Fill="{Binding FillColour, RelativeSource={RelativeSource FindAncestor, AncestorType=RectangleFillTest}}" HorizontalAlignment="Left" Height="50" Stroke="Black" VerticalAlignment="Top" Width="150"/> 

此外,在您的依賴屬性,它的類型應該是刷機,而不是字符串。

4

您的依賴項屬性有兩個錯誤。

首先,它的類型應該是Brush,而不是字符串,因爲這是WPF控件的屬性使用的類型,如Shape.FillControl.Background。 WPF提供了從XAML中的「Red」或「#FFFF0000」等字符串到類型Brush的自動類型轉換。其次,在CLR包裝器的setter方法中,除了調用SetValue之外,你不應該有任何其他的東西。究其原因,在XAML Loading and Dependency Properties文章解釋MSDN上:

因爲對於屬性設置當前WPF實現XAML處理器行爲 完全繞過了包裝,你不應該 提出任何額外的邏輯到的一組定義包裝爲 您的自定義依賴屬性。如果在定義集 中放入這樣的邏輯,那麼當在XAML中設置屬性 而不是在代碼中時,邏輯將不會執行。

所以,你所依賴的財產申報應該是這樣的:

public static readonly DependencyProperty FillBrushProperty = 
    DependencyProperty.Register(
     "FillBrush", typeof(Brush), typeof(RectangleFillTest)); 

public Brush FillBrush 
{ 
    get { return (Brush)GetValue(FillBrushProperty); } 
    set { SetValue(FillBrushProperty, value); } 
} 

爲了財產的變化作出反應,你現在就註冊屬性的元數據的PropertyChangedCallback。但你並不需要在這裏做的,因爲你可以在屬性只是綁定在用戶控件的XAML這樣的:

<Rectangle Fill="{Binding FillBrush, 
    RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" ... /> 
+0

感謝您的質量解釋,優秀的代碼,也是綁定信息。提示更多絕望的問題,關於如何綁定哪些內容,即將推出。 –

+0

你好克萊門斯,我嘗試了兩種解決方案,都徹底解決了我的問題。我不確定在那種情況下接受哪種禮儀的答案,所以我接受了胡安的那個人,他將從額外的代表中獲得更多的利益。希望這是好的。再次感謝您的時間和精力。 –

+0

你應該接受最能幫助你的答案,並且你認爲最好的答案是。僅僅因爲您認爲作者可以從名譽點獲益而接受答案是錯誤的,並且可能會誤導他人。 – Clemens