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