2014-01-10 208 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