在WPF MVVM中的TreeView中显示嵌套的集合对象

时间:2018-03-15 16:09:04

标签: wpf xaml treeview datatemplate hierarchicaldatatemplate

我是WPF MVVM的新手,面临着一些复杂的情况。 我需要在WPF MVVM中的树视图中显示如下:

TrachineTrades

       TrachineTrade1

           TrachineOrder1

           TrachineOrder2  

       TrachineTrade2 

           TrachineOrder1

           TrachineOrder2

等等。

但我无法为TrachineTrades和TrachineOrders创建HierarchicalDataTemplates的XAML,也无法为TrachineOrder创建DataTemplate以在树视图中显示集合。任何人都可以建议/显示一些代码片段,以便我可以正确显示数据(鉴于这些集合本质上是嵌套在另一个中)。

我有以下课程。

Model Classes:
==================

    SymbolDynamicAttribute.cs

    TrachineTrades.cs

    TrachineTrade.cs

    TrachineOrders.cs

    TrachineOrder.cs

View Model Classes:
====================

    VMSymbolDynamicAttribute.cs

模型类SymbolDynamicAttribute的代码片段:

public class SymbolDynamicAttribute : BaseModel
{
    private TrachineTrades m_TodaysTrades;


    public TrachineTrades TodaysTrades
    {
        get
        {
            return m_TodaysTrades;
        }
    }
}

Model Class TrachineTrades的代码片段:

public class TrachineTrades : BaseCollection<TrachineTrade>
{
    public TrachineTrades() : base() { }
}

Model Class TrachineTrade的代码片段:

   public class TrachineTrade
    {
        private TrachineOrders m_OrdersForThisTrade;

        public TrachineTrade()
        {
            m_OrdersForThisTrade = new TrachineOrders();
        }

    }

Model Class TrachineOrders的代码片段:

public class TrachineOrders : BaseCollection<TrachineOrder>
{
    public TrachineOrders() : base()
    {

    }

}

Model Class TrachineOrder的代码片段:

   public class TrachineOrder
    {
        private decimal m_price;
        private string m_OrderID;
        private DateTime m_OrderPlacedTime;        
        private TRANSACTION_TYPE m_TransactionType;
        public decimal Price
        {
            get
            {
                return m_price;
            }
            set
            {
                m_price = value;
            }
        }
        public string OrderID
        {
            get
            {
                return m_OrderID;
            }
            set
            {
                m_OrderID = value;
            }
        }
        public DateTime OrderPlacedTime
        {
            get
            {
                return m_OrderPlacedTime;
            }
            set
            {
                m_OrderPlacedTime = value;
            }
        }  
        public TRANSACTION_TYPE TransactionType
        {
            get
            {
                return m_TransactionType;
            }
            set
            {
                m_TransactionType = value;
            }
        }
    }

Model Model VMSymbolDynamicAttribute的代码片段:

public class VMSymbolDynamicAttribute : BaseViewModel
{
    SymbolDynamicAttribute m_sda;

    public VMSymbolDynamicAttribute()
    {

    }

    public VMSymbolDynamicAttribute(SymbolDynamicAttribute a_sda)
    {
        m_sda = a_sda;
    }

    public TrachineTrades VM_TodaysTrades
    {
        get
        {
            return m_sda.TodaysTrades;
        }
    }

}

由于

1 个答案:

答案 0 :(得分:0)

考虑我从文本结构查看器中借用和剥离的这个简单视图模型示例。这些类表示文本元素,其中段落可以包含跨度,跨度可以包含更多跨度和运行等。子元素保存在ObservableCollection中,允许UI在集合更改时更新。

    public class TextElement : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public TextElement()
        {

        }

        public virtual ObservableCollection<TextElement> Elements
        {
            get { return m_elements; }
        }

        protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        ObservableCollection<TextElement> m_elements = new ObservableCollection<TextElement>( );
    }

    public class TextRun : TextElement
    {
        public TextRun()
        {

        }

        public String Content
        {
            get { return m_content; }
            set { if (m_content != value) { OnPropertyChanged(); } }
        }

        String m_content;
    }

    public class TextParagraph : TextElement
    {
        public TextParagraph()
        {

        }
    }

要在树状视图中显示它,您可以执行以下操作:

    <TreeView ItemsSource="{Binding RootElement}" >

        <TreeView.Resources>

            <HierarchicalDataTemplate DataType="{x:Type viewmodel:TextParagraph}" ItemsSource="{Binding Elements}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Paragraph" />
                </StackPanel>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType="{x:Type viewmodel:TextSpan}" ItemsSource="{Binding Elements}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Span" />
                </StackPanel>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType="{x:Type viewmodel:TextRun}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Run " />
                    <TextBlock Text="{Binding Content}" FontWeight="Bold" />
                </StackPanel>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType="{x:Type viewmodel:TextLinebreak}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Linebreak" />
                </StackPanel>
            </HierarchicalDataTemplate>

        </TreeView.Resources>
    </TreeView>

没有必要将所有类派生自单个基类,但它们可能都应该实现INotifyPropertyChanged。

还可以在视图模型类中包含bool IsExpanded和IsSelected属性,并将这些属性绑定到树视图项:

<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="FontWeight" Value="Bold" />
            </Trigger>
        </Style.Triggers>
    </Style>
</TreeView.ItemContainerStyle>

这使得可以在树中展开项节点并从视图模型中设置选择状态。