Управление обновлением WPF на месте с использованием xamlreader
-
18-09-2019 - |
Вопрос
У меня есть существующий предмет, который является ребенком холста. Стиль элемента содержится в словаре ресурсов, который содержит различные кисти, которые можно использовать для окрашивания элемента.
Когда экземпляр элемента создается, ему дается раскраска по умолчанию. В настоящее время я не могу напрямую взаимодействовать с свойством заполнения, как в:
item.Fill = BrushBlue;
По этой причине я начал смотреть на XAML для каждого экземпляра предмета.
XAML, который мне интересует, для элемента после создания экземпляра:
<d:Item IsSelected="True" Width="78" Height="65" Panel.ZIndex="0" Canvas.Left="233" Canvas.Top="352.54">
<Path ToolTip="Process">
<Path.Style>
<Style TargetType="Path">
<Style.BasedOn>
<Style TargetType="Path">
<Style.Resources>
<ResourceDictionary />
</Style.Resources>
<Setter Property="Shape.Fill">
<Setter.Value>
<DynamicResource ResourceKey="ItemBrush" />
</Setter.Value>
</Setter>
</Style>
</Style.BasedOn>
</Style>
</Path.Style>
</Path>
.
.
.
</d:Item>
В идеале я хотел бы иметь возможность связывать значение Shape.fill с свойством экземпляра элемента или, по крайней мере, иметь возможность изменить это значение на основе выбора пользователя в приложении.
Я редактирую XAML элемента, чтобы изменить его цвет заполнения. Для этого я использую следующий код, основанный на образец кнопки кнопки от MSDN:
string savedItem = XamlWriter.Save(this) as String;
string newItem = savedItem.Replace(GetFillBrush(this), "BrushBlue");
SetFillBrush(this, "BrushBlue");
StringReader stringReader = new StringReader(newItem);
XmlReader xmlReader = XmlReader.Create(stringReader);
thisCanvas.Children.Add((Item)XamlReader.Load(xmlReader));
Я получаю XAML, обновляю имя ресурса Brush, а затем создаю новый элемент.
Этот подход был доказательством концепции. Я хочу иметь возможность обновить XAML существующего элемента без необходимости создавать новый элемент на холсте.
Как лучше всего выполнить это «на месте» обновление свойства элемента?
Решение
Я предполагаю, что кисть используется в нескольких местах, поэтому вы не можете просто установить свойство заполнения:
item.Fill = Brushes.Blue;
В этом случае вы должны сделать инкапсуляцию элемента в UserControl или пользовательский контроль, с свойством зависимости от кисти типа. (В зависимости от использования кисти вы также можете назвать это заполнением, или она может быть более конкретной, например, Accentfill, Overtorborderfill и т. Д.) Затем в вашем XAML свяжите все эти многочисленные входы кисти с этим свойством. Теперь ваша очередь делать Имейте одно место, где вы можете установить свойство, и через привязки оно будет распространяться во все места, которые он необходимо:
item.AccentFill = Brushes.Blue;
В любом случае, ключом не думать о «обновлении XAML существующего элемента». XAML - это формат сериализации. Ваш существующий элемент уже представляет собой объект .NET в памяти, и вы можете устанавливать свойства напрямую, а не необходимо перезагрузить из сериализованной формы.
Другие советы
Если я не понимаю ваш вопрос, вы В самом деле Делать это трудным путем. Почему это не работает?
this.Fill = Brushes.Blue;
или если важно использовать имя ресурса:
this.Fill = (Brush)FindResource("BlueBrush")
Может быть, вам нужно уточнить свой вопрос, чтобы объяснить, почему вы не можете просто установить ценность и покончить с ним.