选中TreeViewItem时更改前景色

3
在我的程序中,我有一个TreeView,在其中用户将选择不同的项目。在我的C#代码后端中创建时,我的TreeView中有一些自定义的项目。
例如:
public static TreeViewItem newItem = new TreeViewItem() //Child Node
{
       Header = new StackPanel //ICON
       {
           Orientation = Orientation.Horizontal,
           Children =
           {
               new Border {
                   Width = 12,
                   Height = 14,

                   Background = Brushes.Blue,
                   BorderThickness = new Thickness(1.0),
                   BorderBrush = Brushes.Black
              },
              new Label {
                  Content = "Node1"
              }
           }
      }
};

我希望这些项目在被选择时能显示白色前景色(就像默认节点的行为一样)。
以下是我在XAML中尝试过的模板样式,我已经为TreeViewItems设置了它。我没有收到编译器错误,但由于某些原因,当我运行程序时我的TreeView不可见。
<Style TargetType="{x:Type TreeViewItem}" >
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TreeViewItem}">
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True" >
                                <Setter Property="Foreground" Value="White" />
                            </Trigger>
                            <Trigger Property="IsSelected" Value="False" >
                                <Setter Property="Foreground" Value="Black" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
</Style>

我该如何修复这个问题,使得所有选中的TreeView节点都显示白色的前景色?

如果我使用TextBlock,它会允许更改Foreground吗? - Eric after dark
1个回答

2

这是因为您完全重写了模板,而没有在其中编写任何内容。只需设置触发器即可,不一定要在模板中执行它们,您可以将它们设置在Style中。模板通常用于更改可视树中的元素。尝试以下示例:

<Window.Resources>
    <Style TargetType="{x:Type TreeViewItem}">
        <Style.Resources>
            <!-- Set Highlight Background color -->
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Black" />
        </Style.Resources>

        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <!-- Set Foreground color -->
                <Setter Property="Foreground" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <TreeView>
        <TreeViewItem Header="Root">
            <TreeViewItem Header="Child1" />
            <TreeViewItem Header="Child2" />
            <TreeViewItem Header="Child3" />
            <TreeViewItem Header="Child4" />
        </TreeViewItem>
    </TreeView>
</Grid>

更多信息请参见:

MSDN上的样式和模板

TreeView样式/模板示例

编辑

试试这个:

public TreeViewItem newItem = new TreeViewItem() //Child Node
{
    Header = new StackPanel 
    {
        Orientation = Orientation.Horizontal,

        Children =
        {
            new Border 
            {
                Width = 12,
                Height = 14,

                Background = Brushes.Blue,
                BorderThickness = new Thickness(1.0),
                BorderBrush = Brushes.Black
            },

            new Label 
            {
                Content = "Node1",
                Foreground = Brushes.Black,
            }
        }
    }
};

private void AddItem_Click(object sender, RoutedEventArgs e)
{
    // Set Selected handler on Selected event
    newItem.Selected += new RoutedEventHandler(newItem_Selected);

    // Set Unselected handler on Unselected event
    newItem.Unselected += new RoutedEventHandler(newItem_Unselected);

    // Add your item
    MyTreeView.Items.Add(newItem);
}

// Set the black color for foreground
private void newItem_Unselected(object sender, RoutedEventArgs e) 
{
    TreeViewItem MyTreeViewItem = sender as TreeViewItem;
    StackPanel MyStackPanel = MyTreeViewItem.Header as StackPanel;
    Label MyLabel = MyStackPanel.Children[1] as Label;

    MyLabel.Foreground = Brushes.Black;
}

// Set the white color for foreground
private void newItem_Selected(object sender, RoutedEventArgs e)
{
    TreeViewItem MyTreeViewItem = sender as TreeViewItem;
    StackPanel MyStackPanel = MyTreeViewItem.Header as StackPanel;
    Label MyLabel = MyStackPanel.Children[1] as Label;

    MyLabel.Foreground = Brushes.White;         
}

注意: 如果您使用 TreeViewItem 模板,可以缩短和简化此代码。


这适用于所有正常的TreeViewItems,但是我在问题中提到的那些(自定义的)没有受到影响。 - Eric after dark
2
@Ericafterdark,我在你的代码中看不到需要使用 Label 的必要。除非你真的需要它,否则用 TextBlock 替换它,并使用原始、更简单的 Style 解决方案,应该可以立即为你的项目工作。 - dkozl
@Anatoliy Nikolaev,如果我使用按钮单击添加节点,则此答案似乎有效。但是,目前我的Selected Nodes由SelectedItemChanged方法控制。我如何从SelectedItemChanged方法调用这些事件处理程序?@dkozl-将其更改为TextBlock - Eric after dark
@Eric after dark:只需向您的newItem添加两个事件,就像这样:newItem.Selected += new RoutedEventHandler(newItem_Selected);,例如在添加TreeView.Items之前。您知道如何添加吗? - Anatoliy Nikolaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接