2017-03-08 50 views
1

我正在根據UserControl類自定義WPF控件。這是一個簡單的複選框,帶有兩條對角線的矩形,在縮放整個控件時可以正確縮放。這裏是XAML:如何讓WPF UserControl在設計時更新?

<UserControl x:Name="Container" 
    x:Class="MyProject.Controls.VirmanCheckbox" 
    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:MyProject.Controls" 
    mc:Ignorable="d" 
    d:DesignHeight="50" d:DesignWidth="50" BorderThickness="1" BorderBrush="Black" Width="50" Height="50" Cursor="Hand" IsTabStop="True" Focusable="True" KeyUp="Grid_KeyUp" GotFocus="Container_GotFocus" LostFocus="Container_LostFocus"> 
<Grid MouseUp="Grid_MouseUp" Background="#00000000"> 
    <Line x:Name="diagonal1" X1="0" Y1="0" X2="{Binding Width, ElementName=Container}" Y2="{Binding Height, ElementName=Container}" Stroke="{Binding ElementName=Container, Path=BorderBrush}" StrokeThickness="{Binding ElementName=Container, Path=BorderThickness}" Visibility="Hidden"/> 
    <Line x:Name="diagonal2" X1="0" Y1="{Binding Height, ElementName=Container}" X2="{Binding Width, ElementName=Container}" Y2="0" Stroke="{Binding ElementName=Container, Path=BorderBrush}" StrokeThickness="{Binding ElementName=Container, Path=BorderThickness}" Visibility="Hidden"/> 
</Grid> 

我加DependencyProperty IsChecked到CustomControl類。如果IsCheckedtrue對角線應該是可見的。如果IsCheckedfalse對角線應該隱藏。它看起來像這樣:

public partial class CustomCheckbox : UserControl 
{ 
    public static readonly DependencyProperty IsCheckedProperty; 

    static CustomCheckbox() 
    { 
     IsCheckedProperty = DependencyProperty.Register(
      name: "IsChecked", 
      propertyType: typeof(Boolean), 
      ownerType: typeof(VirmanCheckbox), 
      typeMetadata: new FrameworkPropertyMetadata(
       defaultValue: false, 
       flags: FrameworkPropertyMetadataOptions.AffectsRender 
      ) 
     ); 
    } 

    public bool IsChecked 
    { 
     get { return (bool)GetValue(IsCheckedProperty); } 
     set 
     { 
      var old = (bool)GetValue(IsCheckedProperty); 
      SetValue(IsCheckedProperty, value); 

      if (old != value) 
      { 
       if (value) 
       { 
        diagonal1.Visibility = Visibility.Visible; 
        diagonal2.Visibility = Visibility.Visible; 
       } 
       else 
       { 
        diagonal1.Visibility = Visibility.Hidden; 
        diagonal2.Visibility = Visibility.Hidden; 
       } 
      } 
     } 
    } 
} 

當我用我的項目這個控制我得到這樣的XAML:

<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top"/> 

在運行時,它完美的作品,但在設計時,如果我改變IsChecked屬性在XAML我CustomCheckbox不會以圖形方式更新。例如,如果我設置IsCheckedtrue,對角線不會顯示:

<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="True"/> 
<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="False"/> 

這兩個控件是在設計時在視覺上相同。我錯過了什麼?

回答

1

報價MSDN

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

您應該註冊一個PropertyChangedCallback來代替。

public partial class CustomCheckbox : UserControl 
{ 
    public CustomCheckbox() 
    { 
     InitializeComponent(); 
    } 

    #region IsChecked 
    public static readonly DependencyProperty IsCheckedProperty = 
     DependencyProperty.Register("IsChecked", 
      typeof(bool), typeof(CustomCheckbox), 
      new FrameworkPropertyMetadata(
       false, 
       FrameworkPropertyMetadataOptions.AffectsRender, 
       IsCheckedPropertyChanged)); 

    public bool IsChecked 
    { 
     get { return (bool)GetValue(IsCheckedProperty); } 
     set { SetValue(IsCheckedProperty, value); } 
    } 
    #endregion 

    #region IsCheckedPropertyChanged 
    private static void IsCheckedPropertyChanged 
     (DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     if (source is CustomCheckbox) 
     { 
      CustomCheckbox control = source as CustomCheckbox; 
      bool value = (bool)e.NewValue; 

      if (value) 
      { 
       control.diagonal1.Visibility = Visibility.Visible; 
       control.diagonal2.Visibility = Visibility.Visible; 
      } 
      else 
      { 
       control.diagonal1.Visibility = Visibility.Hidden; 
       control.diagonal2.Visibility = Visibility.Hidden; 
      } 
     } 
    } 
    #endregion 
} 

作爲一個方面說明,在WPF中你通常會交換的規律CheckBox模板來改變它的外觀。

+0

你想說我不應該創建一個新組件,而是爲CheckBox實例定義自定義模板?我對WPF仍然很陌生,但我猜想存在這樣做的全球方式? – Djuka