【问题标题】:How can i pass properties to WPF style with DependencyProperty?如何使用 DependencyProperty 将属性传递给 WPF 样式?
【发布时间】:2019-01-31 08:26:32
【问题描述】:

我正在尝试使用 WPF 为按钮创建可重用样式,并且我想从 .xaml 传递参数,但即使我在调试时在 ButtonStyle 类中插入断点时它也无法正常工作,但他没有进入它,我错过了一些东西,我没有找到它。

谢谢。

ButtonStyle 类:

Public Class ButtonStyle
Inherits System.Windows.Controls.Button

Public Sub New()
End Sub

Public Shared ReadOnly BackgroundColorProperty As DependencyProperty = 
DependencyProperty.Register("BackgroundColor", GetType(Brush), 
GetType(ButtonStyle))

Public Property BackgroundColor As Brush
    Get
        Return CType(GetValue(BackgroundColorProperty), Brush)
    End Get
    Set(value As Brush)
        SetValue(BackgroundColorProperty, value)
    End Set
End Property

Public Shared ReadOnly BackgroundColorHoverProperty As DependencyProperty 
= DependencyProperty.Register("BackgroundColorHover", GetType(Brush), 
GetType(ButtonStyle))

Public Property BackgroundColorHover As Brush
    Get
        Return CType(GetValue(BackgroundColorHoverProperty), Brush)
    End Get
    Set(value As Brush)
        SetValue(BackgroundColorHoverProperty, value)
    End Set
End Property

Public Shared ReadOnly BorderColorProperty As DependencyProperty = 
DependencyProperty.Register("BorderColor", GetType(Brush), 
GetType(ButtonStyle))

Public Property BorderColor As Brush
    Get
        Return CType(GetValue(BorderColorProperty), Brush)
    End Get
    Set(value As Brush)
        SetValue(BorderColorProperty, value)
    End Set
End Property

Public Shared ReadOnly BorderColorHoverProperty As DependencyProperty = 
DependencyProperty.Register("BorderColorHover", GetType(Brush), 
GetType(ButtonStyle))

Public Property BorderColorHover As Brush
    Get
        Return CType(GetValue(BorderColorHoverProperty), Brush)
    End Get
    Set(value As Brush)
        SetValue(BorderColorHoverProperty, value)
    End Set
End Property

Public Shared ReadOnly IconeProperty As DependencyProperty = 
DependencyProperty.Register("Icone", GetType(ImageSource), 
GetType(ButtonStyle))

Public Property Icone As ImageSource
    Get
        Return CType(GetValue(IconeProperty), ImageSource)
    End Get
    Set(value As ImageSource)
        SetValue(IconeProperty, value)
    End Set
End Property End Class

MainWindow.xaml:

 <Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="DictionaryResources.xaml"/>
        </ResourceDictionary.MergedDictionaries >
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <local:ButtonStyle Width="150" Height="50" Style="{StaticResource 
StyleBoutonHello}"   Icone="img.png" BorderColor="red" 
BackgroundColor="red" BackgroundColorHover="Blue" BorderColorHover="blue" 
Content="Hello"></local:ButtonStyle>
</Grid>

DictionnaryResource.xaml:

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">

<Style x:Name="StyleBoutonHello" x:Key="StyleBoutonHello" TargetType=" 
{x:Type local:ButtonStyle}">
    <Setter Property="BorderBrush"  Value="{Binding BorderColor}" />
    <Setter Property="Background"  Value="red" />
    <Setter Property="FontSize" Value="14" />
    <Setter Property="FontWeight" Value="Medium" />
    <Setter Property="Cursor" Value="Hand" />
    <Setter Property="Content" Value="Hello" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Image Name="Img" Width="30" Height="30" Source="{Binding 
Icone, RelativeSource={RelativeSource TemplatedParent}}" Stretch="None" 
HorizontalAlignment="Center" VerticalAlignment="Center"/>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Source" TargetName="Img"  
Value="{Binding Icone, RelativeSource={RelativeSource TemplatedParent}}" 
/>
                        <Setter Property="Background" Value="{Binding 
BackgroundColorHover}" />
                    </Trigger>
                </ControlTemplate.Triggers>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>  
</ResourceDictionary>

【问题讨论】:

  • 虽然你叫它ButtonStyle,但它并不是按钮的可复用样式,而只是一个自定义的Button控件,即从Button派生的类。命名相当混乱,需要更改。
  • 另外,当 Button 已经有 Background 和 BorderBrush 时,公开 Brush 类型的 BackgroundColor 和 BorderColor 属性是无稽之谈(并且命名错误)。
  • 除此之外,自定义按钮的 ControlTemplate 会忽略所有这些属性。看看example here 看看它是如何完成的。必须有属性绑定的元素,例如{TemplateBinding Background}。也值得一读:Control Authoring Overview.

标签: wpf vb.net mvvm dynamic dependency-properties


【解决方案1】:

例如:-

1) 实现 INotifyPropertyChanged 接口。

Class MainWindow
 Implements INotifyPropertyChanged

 Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
 Private Sub OnPropertyChanged(ByVal name As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
 End Sub

 Public Shared ReadOnly MyProperty1 As DependencyProperty = DependencyProperty.Register("UserName", GetType(String), GetType(MainWindow), New UIPropertyMetadata(String.Empty))

 Public Property UserName() As String
    Get
        Return DirectCast(GetValue(MyProperty1), String)
    End Get
    Set
        SetValue(MyProperty1, Value)
        OnPropertyChanged("Name")
    End Set
 End Property  
End Class

2) 现在绑定 XAML 中的值

 <TextBlock Text="{Binding UserName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>

现在,每当您更改用户名时,它都会反映到 UI 中!!!。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多