2014-01-10 4 views
2

WrapPanel 내에서 많은 사용자 지정 단추가 동적으로 생성되는 응용 프로그램이 있습니다. 모든 작품을 잘하고 나는 코드의 버튼을 생성 테두리 두께, ImageSource, 콘텐츠 등을 할당 할 수 있어요. 이제 고객은 개별 단추에 테두리 색상을 선택하고 올바른 바인딩 시나리오를 파악할 수 없도록 시도 할 수있는 권한이 필요합니다. WPF에서 가파른 WPF 학습 곡선을 사용하고 있으므로 초기 디자인이 약간 벗어 났을 수 있습니다. 내 generic.xaml을에서WPF 사용자 지정 단추 바인딩 테두리 색

나는 버튼 따라서 지정된 있습니다

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

답변

3

Border.BorderBrush 동적 사용?

그렇다면 몇 가지 방법으로 해결할 수 있습니다.

  • NormalBorderBrushMouseOverBorderBrush를 말에 대한 LauncherButton 두 종속성 속성을 추가하고 Button를 사용할 때 당신이 원하는대로 다음을 설정합니다. 이제 Border 당신이 SteelBlue 또는 PaleGoldenRod을 설정 그것의 스타일 내에서 이것을 사용하는 얻을하는 RelativeSource FindAncestorlocal:LauncherButtonAncestorType 바인딩 적용하고 해당 브러시에 (NormalBorderBrush 또는 MouseOverBorderBrush)

예를 가리 :

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

및 사용 : XAML에서

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

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

Sample Download -이 구현 정도로 쉬워야한다 브러쉬 사용을위한 컨버터를 포함하지 않습니다.

  • 또는 당신은 동적 자원으로 정의 된 두 개의 브러쉬가 있고 당신이 필요로 할 때 사용자 코드에서 그들의 색깔의를 오버라이드 (override) 할 수있다.
  • 또는 이미 가지고있는 버튼의 BorderBrush 속성을 사용하여 TemplateBinding BorderBrush으로 테두리에 적용 할 수 있습니다. 이제 IsMouseOver 상태가 변경 될 때 BorderBrush을 적절히 전환해야한다는 의미입니다.
  • 또는 단추의 Style을 검색하고 Border 요소에 대한 참조를 이름을 통해 찾은 다음 런타임에 조정할 수 있습니다.

개인적으로 옵션 1을 선택했습니다. 마지막으로 변환기를 사용하거나 Binding에서 MVVM을 친숙하게 만듭니다.

+0

고맙습니다. 매우 도움이됩니다. 예를들 수만 있다면, 내 문제와 관련된 문제를 찾을 수 없었습니다. – RedEyedMonster

+0

@RedEyedMonster 접근 방식 1에 대한 예제로 내 게시물을 편집했습니다. 첨부 된 샘플 다운로드를 받아서 시도해 볼 수 있어야합니다. – Viv

+0

Brilliant! 감사 – RedEyedMonster

관련 문제