Есть 2 контрола A типа ControlA и B типа ControlB. В каждом из них я определил свойство зависимости HighlightedProperty типа bool. В стилях по наведению мыши я изменяю это свойство, а по изменению этого свойства меняю цвет фона контрола:
<Style TargetType="{x:Type local:ControlA}">
<Setter Property="Background" Value="{StaticResource BackgroundControlA}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Highlighted" Value="True"/>
</Trigger>
<Trigger Property="Highlighted" Value="true">
<Setter Property="Background" Value="{StaticResource HighlightedColor}"/>
</Trigger>
</Style.Triggers>
</Style>
Я хочу что бы при наведении как на контролА, так и на контролБ выделялись оба контрола, поэтому создаю привязки (создаю в коде, потому что бы контролы будут добавляться и удаляться динамически), но они не работают как должны:
Binding bindingA = new Binding("Highlighted");
bindingA.Source = controlA;
controlB.SetBinding(ControlB.HighlightedProperty, bindingA);
Binding bindingB = new Binding("Highlighted");
bindingB.Source = controlB;
controlA.SetBinding(ControlA.HighlightedProperty, bindingB);
Если оставить обе привязки, то ни один из контролов не будет менять цвет, если убрать одну из них, то только один контрол будет менять цвет при наведении мышью на другой. Подскажите, что я делаю не так?
Причина такого поведения стандартна: в WPF есть строгий порядок определения значения свойства зависимости, при этом явная установка значения имеет самый высокий приоритет. Когда вы пишете controlA.SetBinding(ControlA.HighlightedProperty, bindingB)
— это тоже самое, что если бы вы написали в разметке Highlighted="{Binding ...}"
, т. е. та самая явная установка свойства. Для того, чтобы на свойство действовали триггеры из стиля, установка значения свойства должна быть тоже внутри стиля, т. е. в разметке вместо Highlighted="{Binding ...}"
надо писать <Setter Property="Highlighted" Value="{Binding ...}"/>
в стиле. В коде это могло бы выглядеть как-то так:
// Стиль заморожен, придется создавать новый
var style = new Style(typeof(СontrolA), controlA.Style);
var setter = new Setter(ControlA.HighlightedProperty, new Binding(...));
style.Setters.Add(setter);
controlA.Style = style;
Но когда вы это сделаете, вы столкнетесь еще с одной проблемой — после первого наведения цвет фона поменяется и назад уже не вернется, т. к. привязка будет в приоритете перед триггером.
Выход есть и он — отказаться от привязки вообще, действовать только через триггеры, т. е. нужно во второй контрол добавить триггер на изменение IsMouseOver
первого и наоборот (тут вы поймете, что дополнительное свойство Highlighted
вам не нужно вовсе):
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HighlightedColor}"/>
</Trigger>
<DataTrigger Binding="{Binding ElementName=controlB, Path=IsMouseOver}" Value="True">
<Setter Property="Background" Value="{StaticResource HighlightedColor}"/>
</DataTrigger>
</Style.Triggers>
Или, в коде:
var style = new Style(typeof(ControlA), controlA.Style);
var setter = new Setter(BackgroundProperty, Resources["HighlightedColor"]);
var dataTrigger = new DataTrigger
{
Binding = new Binding("IsMouseOver") { Source = controlB },
Value = true,
Setters = { setter }
};
style.Triggers.Add(dataTrigger);
ControlA.Style = style;
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Всем привет, стала интересна возможность работы с несколькими экранами из UWP (такое вообще реально)Есть задача: написать приложение, которое...
Подскажите, как составить DQL для symfony 4 Doctrine для такого sql запроса?