2014-01-10 203 views
2

我有一個應用程序,其中一些自定義按鈕是在WrapPanel內動態生成的。所有工作正常,我可以分配邊框厚度,ImageSource,內容等,因爲我生成代碼中的按鈕。客戶現在有一個要求,允許他們爲單個按鈕選擇邊框顏色,並嘗試一下,因爲我可能無法找出正確的綁定方案。我在這裏是一個陡峭的WPF學習曲線,所以可能是我的初始設計有點不合格。WPF在自定義按鈕中綁定邊框顏色

在我Generic.XAML我有這樣的按鈕指定:

<Style TargetType="{x:Type local:LauncherButton}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type local:LauncherButton}"> 
         <Border Name="LauncherButtonBorder" BorderThickness="{TemplateBinding BThickness}" 
           CornerRadius="10" Background="White" > 

          <Border.Style> 
           <Style TargetType="{x:Type Border}"> 
            <Setter Property="BorderBrush" Value="SteelBlue" /> 

            <Style.Triggers> 
             <Trigger Property="IsMouseOver" Value="True"> 
              <Setter Property="BorderBrush" Value="PaleGoldenrod" /> 
             </Trigger> 
            </Style.Triggers> 

           </Style> 
          </Border.Style> 
          <DockPanel LastChildFill="True" Background="White" Margin="3"> 
           <TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center" 
              Foreground="{DynamicResource TaskButtonTextBrush}" FontWeight="Bold" 
              Margin="5,0,0,0" VerticalAlignment="Center" FontSize="10" 
              Background="Transparent" DockPanel.Dock="Bottom" TextWrapping="Wrap" /> 
           <Image Source="{TemplateBinding ImageSource}" Stretch="Uniform" /> 
          </DockPanel> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

我想在C#中動態地改變當前設置爲靜態鋼青和淡金黃的邊框顏色。

的按鈕類是這樣定義:

public class LauncherButton : ButtonBase 
    { 
     static LauncherButton() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(LauncherButton), new FrameworkPropertyMetadata(typeof(LauncherButton))); 
     } 

     public ImageSource ImageSource 
     { 
      get { return (ImageSource)GetValue(ImageSourceProperty); } 
      set { SetValue(ImageSourceProperty, value); } 

     } 

     public Thickness BThickness 
     { 
      get { return (Thickness) GetValue(BThicknessProperty); } 
      set { SetValue(BThicknessProperty,value);} 
     } 



       public static readonly DependencyProperty ImageSourceProperty = 
      DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(LauncherButton), new UIPropertyMetadata(null)); 

     public static readonly DependencyProperty BThicknessProperty = 
      DependencyProperty.Register("BThickness", typeof(Thickness), typeof(LauncherButton), new UIPropertyMetadata(null)); 


    } 

,我結合一些屬性爲下面的類的實例:

public class CustomButton:INotifyPropertyChanged 
{ 
    private string _type; 
    private string _buttonId; 
    private string _name; 
    private string _image; 
    private string _link; 
    private string _parent; 
    private List<CustomButton> _children; 
    private bool _isExpanded; 
    private bool _isSelected; 


    public string ButtonId 
    { 
     get { return _buttonId; } 
     set 
     { 
      if (value == _buttonId) return; 
      _buttonId = value; 
      OnPropertyChanged("ButtonId"); 
     } 
    } 

    public string Type 
    { 
     get { return _type; } 
     set 
     { 
      if (value == _type) return; 
      _type = value; 
      OnPropertyChanged("Type"); 
     } 
    } 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (value == _name) return; 
      _name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 

    public string Image 
    { 
     get { return _image; } 
     set 
     { 
      if (value == _image) return; 
      _image = value; 
      OnPropertyChanged("Image"); 
     } 
    } 

    public string Link 
    { 
     get { return _link; } 
     set 
     { 
      if (value == _link) return; 
      _link = value; 
      OnPropertyChanged("Link"); 
     } 
    } 

    public string Parent 
    { 
     get { return _parent; } 
     set 
     { 
      if (value == _parent) return; 
      _parent = value; 
      OnPropertyChanged("Parent"); 
     } 
    } 

    public List<CustomButton> Children 
    { 
     get { return _children; } 
     set 
     { 
      if (Equals(value, _children)) return; 
      _children = value; 
      OnPropertyChanged("Children"); 
     } 
    } 

    public bool IsExpanded 
    { 
     get { return _isExpanded; } 
     set 
     { 
      if (value.Equals(_isExpanded)) return; 
      _isExpanded = value; 
      OnPropertyChanged("IsExpanded"); 
     } 
    } 

    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set 
     { 
      if (value.Equals(_isSelected)) return; 
      _isSelected = value; 
      OnPropertyChanged("IsSelected"); 
     } 
    } 


    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

回答

3

你試圖讓這兩個刷用於Border.BorderBrush動態?

如果是這樣,你可以通過幾種方式解決它。

  • 添加兩個依賴屬性LauncherButton的發言權NormalBorderBrushMouseOverBorderBrush,然後將其設置爲你希望當您使用Button。現在拿到Border利用這一點,它的風格,您可以設置SteelBluePaleGoldenRod內,應用RelativeSource FindAncestorlocal:LauncherButtonAncestorType結合並將其指向相應的刷機(NormalBorderBrushMouseOverBorderBrush

例子:

<Border.Style> 
    <Style TargetType="{x:Type Border}"> 
    <Setter Property="BorderBrush" 
      Value="{Binding RelativeSource={RelativeSource FindAncestor, 
                  AncestorType={x:Type local:LauncherButton}}, 
          Path=NormalBorderBrush}" /> 
    <Style.Triggers> 
     <Trigger Property="IsMouseOver" 
       Value="True"> 
     <Setter Property="BorderBrush" 
       Value="{Binding RelativeSource={RelativeSource FindAncestor, 
                   AncestorType={x:Type local:LauncherButton}}, 
           Path=MouseOverBorderBrush}" /> 
     </Trigger> 
    </Style.Triggers> 
    </Style> 
</Border.Style> 

和口服:

public class LauncherButton : ButtonBase { 
    ... 

    public static readonly DependencyProperty NormalBorderBrushProperty = 
    DependencyProperty.Register("NormalBorderBrush", typeof(Brush), typeof(LauncherButton), 
     new UIPropertyMetadata(Brushes.Blue)); 

    public static readonly DependencyProperty MouseOverBorderBrushProperty = 
    DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(LauncherButton), 
     new UIPropertyMetadata(Brushes.Red)); 

    public Brush NormalBorderBrush 
    { 
    get { return (Brush)GetValue(NormalBorderBrushProperty); } 
    set { SetValue(NormalBorderBrushProperty, value); } 
    } 

    public Brush MouseOverBorderBrush 
    { 
    get { return (Brush)GetValue(MouseOverBorderBrushProperty); } 
    set { SetValue(MouseOverBorderBrushProperty, value); } 
    } 
} 
在XAML

<local:LauncherButton BThickness="5" 
         Content="Hellooooo" 
         MouseOverBorderBrush="Green" 
         NormalBorderBrush="Aqua" /> 

Sample Download - 這不包含刷機使用的轉換器,這應該是很容易實現的。

  • OR你可以有定義爲動態資源的兩把刷子,當你需要從你的代碼重寫它們的顏色的。
  • 您可以使用已具有的按鈕的BorderBrush屬性,並將其應用於邊框,並使用TemplateBinding BorderBrush。現在這意味着當你的IsMouseOver狀態改變發生時,你需要相應地切換BorderBrush
  • OR,你甚至可以去檢索按鈕的Style並通過它發現它越來越爲Border元素的引用的名稱,然後在運行時調整它的範圍。

就我個人而言,我會選擇選項1.最後使用轉換器或同樣在綁定使MVVM友好。

+0

非常感謝您的幫助。如果你能舉一個例子,那將是非常好的,我一直無法找到一個與我的問題相關的問題。 – RedEyedMonster

+0

@RedEyedMonster我已經用方法一的例子編輯了我的帖子。你應該能夠獲得附加的示例下載並從中嘗試。 – Viv

+0

太棒了!謝謝 – RedEyedMonster