Я - инженер FPGA, работающий над разработкой графического интерфейса и совершенно новый для WPF и XAML, поэтому, пожалуйста, прости меня за плохой технический лексикон.
Я хочу показать дерево сетей и членов их узлов. Я основал свой TreeView на рекомендациях, приведенных в этого руководства на основе привязки данных и нескольких HierarchicalDataTemplate.
Я хочу, чтобы изображение каждого узла зависело от значения свойства узла, называемого IconColour, которое будет информировать пользователя, если этот узел подключен (зеленый кружок) или отключен (красный кружок), и еще немного, но это дает идею. Во время выполнения программы узел может переключать свое состояние между подключенным и отключенным.
Мне удалось привязать изображение узла к значению свойства public Icon_colour Icon;
, используя <Image Source="{Binding DisplayedImagePath}" Height="12" Width="12" Margin="0,0,5,0"/>
, где DisplayedImagePath возвращает строку с именем файла изображения в зависимости от значения переменной Icon
.
Это соответствующий код XAML TreeView
<TreeView Name="trvNetworks" Background="Transparent">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:NetworkList}" ItemsSource="{Binding Networks}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="New Network" Click="NewNetwork_Click"></MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:Network}" ItemsSource="{Binding Nodes}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Nodes" Click="AddNodes_Click"></MenuItem>
<MenuItem Header="Delete Network" Click="DeleteNetwork_Click"></MenuItem>
<MenuItem Header="Config Network" Click="ConfigNetwork_Click"></MenuItem>
<MenuItem Header="Query Network" Click="QueryNetwork_Click"></MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Text="{Binding Nodes.Count}" Foreground="Blue" />
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:Node}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding DisplayedImagePath}" Height="12" Width="12" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete Node" Click="DeleteNode_Click"></MenuItem>
<MenuItem Header="Config Node" Click="ConfigNode_Click"></MenuItem>
<MenuItem Header="Query Node" Click="QueryNode_Click"></MenuItem>
<MenuItem Header="Display Info" Click="DisplayInfo_Click"></MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
Это класс узла
public class Node
{
public string Name { get; set; }
public string Phone_number { get; set; }
public string Network_name { get; set; }
public string File_name { get; set; }
public enum Icon_colour
{
green,
yellow,
red,
black
};
public Icon_colour Icon;
public string DisplayedImagePath
{
get
{
switch (Icon)
{
case Icon_colour.green:
return @"D:/projects/010_ECR/ecr_gui/EcrGui/bin/Debug/images/circle_green.png";
case Icon_colour.yellow:
return @"D:/projects/010_ECR/ecr_gui/EcrGui/bin/Debug/images/circle_yellow.png";
case Icon_colour.red:
return @"D:/projects/010_ECR/ecr_gui/EcrGui/bin/Debug/images/circle_red.png";
case Icon_colour.black:
return @"D:/projects/010_ECR/ecr_gui/EcrGui/bin/Debug/images/circle_black.png";
default:
return @"D:/projects/010_ECR/ecr_gui/EcrGui/bin/Debug/images/circle_black.png";
}
}
}
}
Когда я инициализирую каждый узел, я вижу, что изображение отображается правильно в соответствии со значением, заданным для Icon
. Затем я меняю стоимость имущества на событие ConfigNode_Click
private void ConfigNode_Click(object sender, RoutedEventArgs e)
{
var baseobj = sender as FrameworkElement;
var myObject = baseobj.DataContext as Node;
// find the network where the node belongs to, delete the node, update the empy_network list, update the node_dictionary
for (int i = 0; i < network_list.Networks.Count; i++)
{
// network has been found
if (network_list.Networks[i].Name == myObject.Network_name)
{
// find the node
for (int j = 0; j < network_list.Networks[i].Nodes.Count; j++)
{
if (network_list.Networks[i].Nodes[j].Name == myObject.Name)
{
MessageBox.Show(network_list.Networks[i].Nodes[j].Name);
network_list.Networks[i].Nodes[j].Icon = Node.Icon_colour.yellow;
// update node_dictionary
node_dictionary[network_list.Networks[i].Nodes[j].Name].Icon = Node.Icon_colour.yellow;
break;
}
}
break;
}
}
}
Значение корректно обновляется, но TreevView не обновляет изображение . Однако, если удалить узел из дерева, а затем добавить его снова, изображение корректно обновляется.
Итак, может ли кто-нибудь помочь мне, как уведомить TreeView, что изображение должно быть обновлено после изменения значения Icon
?
Я прочитал много разных постов, но не могу найти решение этой конкретной проблемы.