【问题标题】:How come left-click on the TreeViewItems that are created with DataTemplate does not select them?为什么左键单击使用 DataTemplate 创建的 TreeViewItems 不会选择它们?
【发布时间】:2013-07-10 14:14:48
【问题描述】:
<TreeView Name="MyTreeView" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
    <TreeView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </TreeView.ItemsPanel>
    <TreeView.Resources>
        <DataTemplate DataType="{x:Type EntityType:MyFixedDevice}">
            <TreeViewItem IsHitTestVisible="True" IsEnabled="True">
            <TreeViewItem.Header>
                <TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource NameConverter}}"
                           IsHitTestVisible="True" IsEnabled="True"/>
            </TreeViewItem.Header>
            </TreeViewItem>
        </DataTemplate>
    </TreeView.Resources>
    <TreeView.Items>
        <TreeViewItem Header="Data Warehouse">
            <TreeViewItem.Items>
                <TreeViewItem Header="Platforms">
                   <TreeViewItem.Items>
                       <TreeViewItem ItemsSource="{Binding OBJS, Converter={StaticResource COBJSourceConverter}, ConverterParameter=Fixed}">
                           <TreeViewItem.Header>
                               <TextBlock Text="{Binding RelativeSource={RelativeSource Self},
                                          Path=Parent.Items.Count,
                                          StringFormat=Fixed Devices ({0})}">
                               </TextBlock>
                           </TreeViewItem.Header>
                       </TreeViewItem>
                  </TreeViewItem.Items>
                </TreeViewItem>
            </TreeViewItem.Items>
        </TreeViewItem>
    </TreeView.Items>
</TreeView>

为什么用 DataTemplate 创建的 TreeViewItems 左键单击没有选中它们?为什么我在代码中选择它们,我不能再次选择它们或取消它们?

TreeViewItem selectedItem = MyTreeView.SelectedItem as TreeViewItem;
if(selectedItem != null) {
    selectedItem.IsSelected = false;
    MyTreeView.Focus();
}

我尝试使用以下方法取消选择 TreeView 中的 TreeViewItems,但它只会取消选择 TreeViewItems 如果它们是在 XAML 中静态设置的,而不是如果它们是使用 ItemsSource 创建的和DataTemplate?

【问题讨论】:

    标签: c# wpf xaml datatemplate treeviewitem


    【解决方案1】:

    您是否真的要为您的固定设备使用TreeViewItem 模板做一些特别的事情(这需要更改TreeViewItem 模板?

    从表面上看,您似乎可以让TreeView 处理它自己的项目,而只需使用一个简单的模板来表示您的对象:例如

    <DataTemplate DataType="{x:Type EntityType:MyFixedDevice}">
        <TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource NameConverter}}" />
    </DataTemplate>
    

    我可能误解了你想要达到的目标。

    【讨论】:

    • 嗯...我认为我需要创建一个TreeViewItem 对象才能进入TreeViewItem.Items,否则它不会被视为这样,但这对我有用。
    • 我相信,因为 TreeView 继承自 ItemsControl,它会自动将所有项目包装在适当的容器中 (TreeViewItem)。我想在模板中添加另一个 TreeViewItem 意味着它被包装了两次,事情变得有点混乱。
    【解决方案2】:

    当您设置ItemSource 时,SelectedItem 对应于您设置的ItemSource 集合的类型T 中的DataContext 类型,而不是实际的TreeViewItem

    这就是你的演员失败的原因。

    现在,当您直接在 xaml 中创建它们而不设置 ItemSource 时,SelectedItem 只是 TreeViewitem 本身,as 转换工作正常。

    更新:

    与你的DataTemplate无关

    试试这个:

    <Window.Resources>
      <x:Array x:Key="someArray"
                Type="sys:String">
        <sys:String>Hello</sys:String>
        <sys:String>World</sys:String>
      </x:Array>
    </Window.Resources>
    <StackPanel>
      <TreeView x:Name="MyTreeView"
                ItemsSource="{DynamicResource someArray}" />
      <Button Click="ButtonBase_OnClick"
              Content="Some" />
    </StackPanel>
    

    和代码隐藏:

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
      TreeViewItem selectedItem = MyTreeView.SelectedItem as TreeViewItem;
      if (selectedItem != null) {
        selectedItem.IsSelected = false;
        MyTreeView.Focus();
      } else {
        Debug.WriteLine("Not TreeViewitem");
        Debug.WriteLine(MyTreeView.SelectedItem);
      }
    }
    

    现在当应用程序运行时点击一个项目,然后点击Button

    检查输出窗口,你会看到

    Not TreeViewitem
    Hello
    

    DataTemplate 仅有助于在视图中可视化自定义数据类型。这是集合绑定到TreeView时的预期行为

    解决方案:

    在你的情况下获得实际的TreeViewItem 尝试:

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
      TreeViewItem selectedItem =
        MyTreeView.ItemContainerGenerator.ContainerFromItem(MyTreeView.SelectedItem) as TreeViewItem;
      if (selectedItem == null)
        return;
      selectedItem.IsSelected = false;
      MyTreeView.Focus();
    }
    

    ^^ 这应该不适用于HierarchicalDataTemplate。更多选项请参考this

    【讨论】:

    • 但我使用DataTemplate 为类型T 创建TreeViewItem
    • @Bob。它与您的DataTemplate 无关,请查看我对答案的更新。
    • @Bob。根据您的要求,我在答案的底部添加了一个解决方案。试试看是否适合你。
    猜你喜欢
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    相关资源
    最近更新 更多