Прикрепить свойство зависимости к пользовательскому элементу управления

Как зарегистрироваться DependencyProperty на Rectangle заполнить, чтобы я мог динамически менять цвет?

<UserControl.Resources>
    <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Rectangle Stroke="Black">
                            <Rectangle.Fill>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FF48B6E4" Offset="0.013"/>
                                    <GradientStop Color="#FF091D8D" Offset="1"/>
                                </LinearGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsFocused" Value="True"/>
                        <Trigger Property="IsDefaulted" Value="True"/>
                        <Trigger Property="IsMouseOver" Value="True"/>
                        <Trigger Property="IsPressed" Value="True"/>
                        <Trigger Property="IsEnabled" Value="False"/>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<Grid x:Name="LayoutRoot">
    <Button Style="{DynamicResource ButtonStyle1}"/>
    <TextBlock
        x:Name="NodeName"
        x:FieldModifier="public"
        Text="Property"
        Margin="8"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        TextWrapping="Wrap" 
        TextAlignment="Center"
        FontFamily="Segoe Print"
        FontWeight="Bold" 
        Foreground="White"
        FontSize="40"/>
</Grid>

3 ответа

Решение

Почему бы вам не связать Fill к Background свойство кнопки:

<ControlTemplate TargetType="{x:Type Button}"> 
    <Grid> 
        <Rectangle Stroke="Black" Fill="{TemplateBinding Background}" /> 
        ...
    </Grid> 
    ...
</ControlTemplate> 

а затем установить Background как это:

<Button Style="{DynamicResource ButtonStyle1}">
    <Button.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">   
            <GradientStop Color="#FF48B6E4" Offset="0.013"/>   
            <GradientStop Color="#FF091D8D" Offset="1"/>   
        </LinearGradientBrush>   
    </Button.Background>
</Button> 

Если у вас есть собственное свойство зависимости, называемое MyProperty зарегистрирован в вашем UserControlВы можете связать это так:

...
<Rectangle Stroke="Black" Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Parent.Parent.MyProperty}" />
...

Никаких других изменений не требуется.

Это связывает Fill свойство parent родительского элемента управления, которому назначен стиль, в вашем случае UserControl сам.

Используя этот метод, вы можете не только привязать его к свойствам UserControl, но также и к свойствам других элементов управления.

Я бы создал свойство зависимости для вашего представления YourUserControl, что-то вроде этого (для краткости я удалил некоторые из вашей разметки):

<UserControl.Resources>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Rectangle Stroke="Black" Fill="{TemplateBinding Background}">
                    </Rectangle>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Grid x:Name="LayoutRoot">
    <Button Style="{DynamicResource ButtonStyle1}" Background="{Binding DynamicColor}"/>
</Grid>

Затем в YourUserControl.xaml.cs вы можете создать свойство зависимости:

    private My_ViewModel _viewModel
    {
        get { return this.DataContext as My_ViewModel; }
    }

    public LinearGradientBrush DynamicColor
    {
        get { return (string)GetValue(DynamicColorProperty); }
        set { SetValue(DynamicColorProperty, value); }
    }
    public static readonly DependencyProperty DynamicColorProperty =
        DependencyProperty.Register("DynamicColor", typeof(LinearGradientBrush), typeof(YourUserControl),
        new PropertyMetadata(new PropertyChangedCallback(OnDynamicColorPropertyChanged)));

    private static void OnDynamicColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((YourUserControl)d).OnTrackerInstanceChanged(e);
    }

    protected virtual void OnDynamicColorPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        this._viewModel.DynamicColor = e.NewValue;
    }

public class My_ViewModel : INotifyPropertyChanged
{
    public LinearGradientBrush DynamicColor
    {
        get { return dynamicColor; }
        set 
        { 
            if(dynamicColor != value)
            {
                dynamicColor = value;
                OnPropertyChanged("DynamicColor");
            }
        }
    }
    private LinearGradientBrush dynamicColor;
}

Этот подход дает вам полный контроль над значением свойства DynamicColor, а также позволяет эффективно тестировать поведение модуля.

Другие вопросы по тегам