Привязка цвета к свойству DependencyProperty в UserControl

#wpf #colors

#wpf #Цвет

Вопрос:

У меня есть, UserControl который имеет свойство Grid с Background привязкой. Все мои другие привязки работают как ожидалось, но по какой-то причине единственный цвет, который я получаю в своем UserControl , — это значение по умолчанию, которое я установил для DependencyProperty .

Ссылка на UserControl в MainWindow.xaml :

 <controls:MyUserControl Title="{Binding Path=MyObjects[0].Title" MyControlColor="{Binding Path=MyObjects[0].Color}" />
  

Title отображается, как ожидалось, но цвет не изменился.

MyUserControl код (я использую MyControlColorBrush для источника цвета, который просто преобразуется MyControlColor в SolidColorBrush . Код продолжается.):

 <Grid Background="{Binding Path=MyControlColorBrush, RelativeSource={RelativeSource AncestorType=UserControl}}">
    <TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Grid>
  

MyUserControl.xaml.cs код:

 public Color MyControlColor
{
    get { return (Color)GetValue(MyControlColorProperty); }
    set { SetValue(MyControlColorProperty, value); }
}
    public static readonly DependencyProperty MyControlColorProperty = DependencyProperty.Register("MyControlColor", typeof(Color), typeof(MyUserControl), new PropertyMetadata(Colors.Black));
  

А затем свойство, которое просто преобразует цвет в SolidColorBrush :

 public SolidColorBrush MyControlColorBrush
{
    get { return new SolidColorBrush(MyControlColor); }
}
  

Есть идеи о том, чего мне может не хватать? Если я проверю значение MyControlColor , оно показывает правильный цвет, но фон Grid просто не меняется от Black .

Ответ №1:

Привязка к MyControlColorBrush выполняется только один раз при первой загрузке вашей страницы. Ваша привязка к MyObjects[0].Color приводит к обновлению вашего свойства dependency, но ничто не указывает остальной части вашего приложения, что MyControlColorBrush также нуждается в обновлении.

Для достижения этой цели есть несколько способов, самый простой, вероятно, просто создать свойство зависимости только для чтения для вашей кисти, которое вы обновляете всякий раз, когда обнаруживаете изменение в своем свойстве color (это похоже на то, как работают свойства Width / ActualWidth). Вашему элементу управления потребуется DP для цвета:

 public Color MyControlColor
{
    get { return (Color)GetValue(MyControlColorProperty); }
    set { SetValue(MyControlColorProperty, value); }
}

public static readonly DependencyProperty MyControlColorProperty =
    DependencyProperty.Register("MyControlColor", typeof(Color), typeof(MyUserControl),
        new PropertyMetadata(Colors.Black, OnColorChanged));
  

А затем DP, доступный только для чтения, для кисти:

 public Brush MyControlColorBrush
{
    get { return (Brush)GetValue(MyControlColorBrushProperty); }
    protected set { SetValue(MyControlColorBrushPropertyKey, value); }
}

private static readonly DependencyPropertyKey MyControlColorBrushPropertyKey
        = DependencyProperty.RegisterReadOnly("MyControlColorBrush", typeof(Brush), typeof(MyUserControl),
                new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.None));

public static readonly DependencyProperty MyControlColorBrushProperty = MyControlColorBrushPropertyKey.DependencyProperty;
  

И вы будете обновлять кисть всякий раз, когда меняется ваш цветовой DP:

 private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    (d as MyUserControl).MyControlColorBrush = new SolidColorBrush((Color)e.NewValue);
}
  

Элементы GUI в вашем пользовательском элементе управления затем привязываются к DP, доступному только для чтения, например:

 <Grid Background="{Binding Path=MyControlColorBrush, RelativeSource={RelativeSource AncestorType=local:MyUserControl}}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
  

Комментарии:

1. Спасибо! В итоге я использовал части этого, и это отлично работает. Я избавился от своего обычного свойства ColorBrush и создал с его помощью свойство dependency, затем я создал метод ColorPropertyChanged и назначил цвета следующим образом … (источник как MyUserControl). MyControlColorBrush = новый SolidColorBrush((источник как MyUserControl). MyControlColor);