WPF ComboBoxに埋め込まれたTreeViewの実現(MVVM)

WPF ComboBoxに埋め込まれたTreeViewの実現(MVVM)

プロジェクトのために、ComboBoxコントロールにツリー構造が必要です。

最后更新 2022/11/01 21:31
hlpinghcg
预计阅读 4 分钟
分类
WPF
专题
WPF MVVMフレームワークPrismシリーズ
标签
.NET C# WPF 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>
  • 引用 MVVM 库,可以参考:WPF MVVM 通用封装库
  • [バックグラウンドロジック] ViewModelコマンドの宣言と使用
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

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2024/01/25

C#WPFにおけるFluentValidationの使用

この記事では、C#WPFプロジェクトでFluentValidationをプロパティ検証に使用する方法を詳しく見て、MVVMパターンでこれを実装する方法を示します。

继续阅读
同分类 / 同标签 2023/06/11

7/7

NET Core3環境でMVVMフレームワークPrismのダイアログサービスを使用する方法は、prismシリーズの最後の記事です。

继续阅读
同分类 / 同标签 2023/06/11

6/7

NET Core3でMVVMフレームワークを使用する方法Prism地域ベースのナビゲーションシステム

继续阅读
同分类 / 同标签 2023/06/11

5/7

NET Core3環境でMVVMフレームワークを使用する方法Prismのゾーンマネージャを使用したビューの管理

继续阅读