WPF控件之TreeView扩展应用(一)

发布于:2022-07-17 ⋅ 阅读:(202) ⋅ 点赞:(0)

         经过前两章文章所述,对treeview有了理解,那么我们就扩展它的应用范围,走起。

假设我遇见一个需求,如图所示

 有个下拉框,每个子项还能继续分,这种需求用WPF怎么实现?

        简单分析需求可知:下拉框—》ComboBox,子项还能分—》就是递归结构,我就想到用treeview。

        那就写代码吧,还是老样子,基础的就不说了,如图

其中DelegateCommand和BindableObject 是上一篇的内容,这就不展示代码了。

    public class TreeModel : BindableObject
    {
        private string name;

        public string Name
        {
            get => name;
            set
            {
                name = value;
                OnPropertyChanged();
            }
        }

        public ObservableCollection<TreeModel> Children { get; set; } = new ObservableCollection<TreeModel>();
    }

结构很简单,就一个展示属性。

view代码如图所示,没什么难道,用到的也是上篇讲过的知识点(可能不懂的是ScrollViewer.CanContentScroll,如果是false,内容展示会有这种情况,一半展示,一半没展示,true则是,你不管怎么滑动,展示的内容都是完整的)

    <Grid>
        <ComboBox
            Width="200"
            Height="30"
            HorizontalAlignment="Center"
            VerticalContentAlignment="Center"
            IsEditable="True"
            IsReadOnly="True"
            ScrollViewer.CanContentScroll="True"
            ScrollViewer.VerticalScrollBarVisibility="Auto"
            Text="{Binding SelectItem.Name, Mode=TwoWay}">
            <ComboBoxItem MinHeight="40" MaxHeight="300">
                <ComboBoxItem.Template>
                    <ControlTemplate>
                        <ComboBoxItem Width="210">
                            <TreeView
                                x:Name="tree"
                                Width="200"
                                ItemsSource="{Binding TreeModels}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="SelectedItemChanged">
                                        <i:InvokeCommandAction Command="{Binding DataContext.Selected, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}" CommandParameter="{Binding ElementName=tree}" />
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                                <TreeView.ItemTemplate>
                                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                        <TextBlock
                                            Grid.Column="1"
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center"
                                            FontFamily="Palatino Linotype"
                                            Text="{Binding Name}">
                                        </TextBlock>
                                    </HierarchicalDataTemplate>
                                </TreeView.ItemTemplate>
                            </TreeView>
                        </ComboBoxItem>
                    </ControlTemplate>
                </ComboBoxItem.Template>
                <ComboBoxItem />
            </ComboBoxItem>
        </ComboBox>
    </Grid>

viewModel也一样简单,就不叙述了

    public class MainViewModel : BindableObject
    {
        public ObservableCollection<TreeModel> TreeModels { get; set; } = new ObservableCollection<TreeModel>();

        private TreeModel selectItem;

        public TreeModel SelectItem
        {
            get => selectItem;
            set
            {
                selectItem = value;
                Console.WriteLine(SelectItem);
                OnPropertyChanged();
            }
        }

        public DelegateCommand<TreeView> Selected { get; private set; }

        public MainViewModel()
        {
            Selected = new DelegateCommand<TreeView>(Tree_SelectedItemChanged);
            CreateTree();
        }

        private void CreateTree()
        {

            for (int i = 0; i < 5; i++)
            {

                TreeModel treeModel = new TreeModel()
                {
                    Name = $"我是{i}"
                };

                TreeModels.Add(treeModel);

                for (int j = 0; j < 10; j++)
                {
                    treeModel.Children.Add(new TreeModel()
                    {
                        Name = $"我是{i}的{j}个孩子"
                    });
                }
            }
        }

        public void Tree_SelectedItemChanged(TreeView view)
        {
            SelectItem = view.SelectedItem as TreeModel;
        }
    }

运行结果:

 注意:

(1)在编写前端时,注意要在treeview外套一个ComboBoxItem ,原理是这样的,我是拿一个ComboBoxItem 来做下拉内容的展示,然后用ControlTemplate来重写了ComboBoxItem,也就是说,如果不套一个ComboBoxItem,直接用treeview,那么当你点击下拉框看见的内容,其实就是一个ComboBoxItem,那么根据平常的经验,一点下拉宽就消失了,而且展示的内容也会错,套了ComboBoxItem后,treeview其实就是ComboBoxItem的内容,不管你怎么点,都在一个ComboBoxItem中点击的,就不会触发到ComboBox的默认触发器(如果你怒想套也可以去改ComboBox的默认模板)

赠一个小案例,wpf实现上下标

    <TextBlock
        Grid.Column="1"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        FontFamily="Palatino Linotype">
        <Run Text="M" />
        <Run BaselineAlignment="Subscript" Text="2" />
        <Run BaselineAlignment="Superscript" Text="3" />
    </TextBlock>

 它的用途是做一些简单的符号,让用户下拉选中,就不需要用户去手输入了

结束

         这次的内容就这么多,请各位多多批评指正 

本文含有隐藏内容,请 开通VIP 后查看