联系请关注微信公众号:Dotnet9
创建于2022-11-01 21:31:26| hlpinghcg| 我要编辑、留言
WPF ComboBox里嵌入TreeView的实现(MVVM)

本文来自转载。

作者:hlpinghcg

原文标题:WPF ComboBox 里嵌入 TreeView 的实现(MVVM)

原文链接:https://blog.csdn.net/qq_28149763/article/details/126539635

前言

因为项目需要,需要 ComboBox 控件里有树形结构,也在网上看到很多,有复杂的也有简单实现的,自己在实现过程中也遇到了一些问题,在此分享一下自己的实现方式,有问题也欢迎大家私信我共同探讨和指教。

首先我是参考网友的实现方式:WPF 之 Treeview 实现 MVVM 双向绑定

废话不多说,切入正题。。。

Xaml 文件

<StackPanel Orientation="Vertical">
  <ComboBox Name="com" SelectedIndex="{Binding ComboSelected}">
    <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction
          Command="{Binding SelectionChangedCommand}"
          CommandParameter="{Binding ElementName=com,Path=SelectedItem}"
        />
      </i:EventTrigger>
    </i:Interaction.Triggers>
    <ComboBoxItem Content="{Binding ShowName}" Visibility="Collapsed" />
    <ComboBoxItem FocusVisualStyle="{x:Null}">
      <ItemsControl>
        <TreeView
          x:Name="treeView"
          ItemsSource="{Binding TypeList}"
          Height="200"
          Width="{Binding ElementName=com, Path=ActualWidth}"
        >
          <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectedItemChanged">
              <i:InvokeCommandAction
                Command="{Binding SelectItemChangeCommand}"
                CommandParameter="{Binding ElementName=treeView,Path=SelectedItem}"
              />
            </i:EventTrigger>
          </i:Interaction.Triggers>
          <TreeView.Resources>
            <HierarchicalDataTemplate
              DataType="{x:Type m:TypeTreeModel}"
              ItemsSource="{Binding ChildList}"
            >
              <StackPanel Orientation="Horizontal">
                <!--<Image Source="/images/OIP-C.jpg" Width="15" Height="15"/>-->
                <TextBlock Text="{Binding Name}" Margin="3,2" />
                <TextBlock Text=" [" Foreground="Blue" />
                <TextBlock Text="{Binding ChildList.Count}" Foreground="Blue" />
                <TextBlock Text="]" Foreground="Blue" />
              </StackPanel>
              <!--<TextBlock Text="{Binding Name}" Margin="3,2"/>-->
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type m:TypeModel}">
              <StackPanel Orientation="Horizontal">
                <!--<Image Source="/images/OIP-D.jpg" Width="15" Height="15"/>-->
                <!--<TextBlock Text="{Binding Name}" ToolTip="{Binding Id}" Margin="3,2"/>-->
                <TextBlock Text="{Binding Name}" Margin="3,2" />
                <TextBlock Text=" (" Foreground="Green" />
                <TextBlock Text="{Binding Id}" Foreground="Green" />
                <TextBlock Text=" )" Foreground="Green" />
              </StackPanel>
              <!--<TextBlock Text="{Binding Name}" ToolTip="{Binding Id}" Margin="3,2"></TextBlock>-->
            </DataTemplate>
          </TreeView.Resources>
        </TreeView>
      </ItemsControl>
    </ComboBoxItem>
  </ComboBox>
  <!--<TreeView x:Name="treeView" ItemsSource="{Binding TypeList}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectedItemChanged">
                <i:InvokeCommandAction Command="{Binding SelectItemChangeCommand}"
                          CommandParameter="{Binding ElementName=treeView,Path=SelectedItem}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type m:TypeTreeModel}" ItemsSource="{Binding ChildList}">
                <TextBlock Text="{Binding Name}" Margin="3,2"/>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type m:TypeModel}">
                <TextBlock Text="{Binding Name}" ToolTip="{Binding Id}" Margin="3,2"></TextBlock>
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>-->
</StackPanel>

需要注意的是,将直接绑定事件切换到通过 Command 绑定的实现方式:

  • 添加 GuNet 包(搜索 Interactivity)
  • XAML 文件引入:xmlns:i=“clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity”
  • 添加代码
<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
                  CommandParameter="{Binding ElementName=com,Path=SelectedItem}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
SelectItemChangeCommand = new RelayCommand<TypeModel>(onSelectItemChange);
SelectionChangedCommand = new RelayCommand(onSelectionChanged);
  public RelayCommand<TypeModel> SelectItemChangeCommand { get; set; }
  public RelayCommand SelectionChangedCommand { get; set; }

后台逻辑(ViewModel)

public class ViewModel:ViewModelBase
{

    public ObservableCollection<TypeTreeModel> TypeList { get; set; } = new ObservableCollection<TypeTreeModel>();

    public ViewModel()
    {
        TypeList = new ObservableCollection<TypeTreeModel>(GetData());

        SelectItemChangeCommand = new RelayCommand<TypeModel>(onSelectItemChange);
        SelectionChangedCommand = new RelayCommand(onSelectionChanged);
    }

    public RelayCommand<TypeModel> SelectItemChangeCommand { get; set; }
    public RelayCommand SelectionChangedCommand { get; set; }

    private TypeModel selectItem;
    public TypeModel SelectItem
    {
        get { return selectItem; }
        set
        {
            selectItem = value;
            RaisePropertyChanged(() => SelectItem);
        }
    }

    private string showName;
    public string ShowName
    {
        get { return showName; }
        set
        {
            showName = value;
            RaisePropertyChanged(() => ShowName);
        }
    }


    private int comboSelected;
    public int ComboSelected
    {
        get { return comboSelected; }
        set
        {
            comboSelected = value;
            RaisePropertyChanged(() => ComboSelected);
        }
    }


    private List<TypeTreeModel> GetData()
    {
        List<TypeTreeModel> typeTrees = new List<TypeTreeModel>()
        {
            new TypeTreeModel()
            {
                Id = 1,
                Name = "手机",
                ChildList = new ObservableCollection<TypeTreeModel>()
                {
                    new TypeTreeModel(){ Id=2,Name="苹果" },
                    new TypeTreeModel(){ Id=3,Name="华为",
                        ChildList = new ObservableCollection<TypeTreeModel>()
                        {
                            new TypeTreeModel(){Id=4,Name="荣耀" },
                        }},
                    new TypeTreeModel(){ Id=5,Name="小米",
                        ChildList = new ObservableCollection<TypeTreeModel>()
                        {
                            new TypeTreeModel(){Id=6,Name="红米" }
                        }}
                }
            },
            new TypeTreeModel()
            {
                Id=7,
                Name="笔记本",
                ChildList = new ObservableCollection<TypeTreeModel>()
                {
                    new TypeTreeModel(){Id=8,Name="联想"}
                }
            },
            new TypeTreeModel()
            {
                Id=9,
                Name="耳机"
            }
        };
        return typeTrees;
    }

    private void onSelectItemChange(TypeModel type)
    {
        SelectItem=type;
        ShowName = SelectItem.Name;

    }

    private void onSelectionChanged()
    {
        ComboSelected = 0;
    }
}

数据类

public class TypeTreeModel: TypeModel
{
    public ObservableCollection<TypeTreeModel> ChildList { get; set; }
        = new ObservableCollection<TypeTreeModel>();
}

public class TypeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

最终效果

站长尝试以上代码

站长尝试过上面代码,能正常运行,完整代码托管Github

网站统计
网站创建
5年
文章分类
8个
文章总计
471篇
文章原创
101篇(21.44%)