自定义按钮中的WPF绑定边框颜色

时间:2014-01-10 14:31:48

标签: c# wpf xaml data-binding wpf-controls

我有一个应用程序,其中在WrapPanel中动态生成许多自定义按钮。一切正常,我能够在代码中生成按钮时分配边框粗细,ImageSource,内容等。客户现在需要允许他们为各个按钮选择边框颜色,并尝试我可能无法找出正确的绑定方案。我在这里陡峭的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#中动态更改当前设置为静态SteelBlue和PaleGoldenrod的边框颜色。

按钮类的定义如下:

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

1 个答案:

答案 0 :(得分:3)

您是否尝试将两个画笔用于Border.BorderBrush动态?

如果是这样,你可以通过几种方式解决它。

  • LauncherButtonNormalBorderBrush添加两个依赖项属性MouseOverBorderBrush,然后在使用Button时根据需要设置它。现在要让Border使用此功能,在您设置SteelBluePaleGoldenRod的样式中,将RelativeSource FindAncestor绑定与AncestorType应用为local:LauncherButton并将其指向相应的画笔(NormalBorderBrushMouseOverBorderBrush

示例:

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中的

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

和用法:

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

Sample Download - 这不包含刷子使用的转换器,应该很容易实现。

  • OR 您可以将两个画笔定义为动态资源,并在需要时覆盖代码中的颜色。
  • 您可以使用已有的按钮的BorderBrush属性,并将其应用于带有TemplateBinding BorderBrush的边框。现在,这意味着您需要在发生BorderBrush状态更改时相应地切换IsMouseOver
  • 或者你甚至可以去检索按钮Style的范围并通过它的名字找到Border元素的引用,然后在运行时调整它-time。

我个人会选择选项1.最后在Binding中使用转换器或同样使MVVM友好。