【问题标题】:Sorting second level of TreeView and seeing changes... possible?对 TreeView 的第二级进行排序并查看更改...可能吗?
【发布时间】:2011-10-09 22:31:06
【问题描述】:

这是我在这里的第一篇文章,我一直在尝试在其他问题中发现的一些技术,但似乎无法像我想要的那样工作...... 我正在更改现有应用程序(带有 WPF 和 C# 的 .net 3.5,以及带有 sqlserver2008 的实体框架)。我是 EFDM 和 WPF 的新手。 新版本需要与旧版本的现有数据库完全兼容,而不需要对现有数据库进行任何修改,因此我非常不愿意更改数据模型及其生成的任何对象。

无论如何,这是我的问题: 我有来自 edm 的对象“员工激励”和“员工激励”,每个员工激励都有 0 到多个员工激励行。 我将它们显示为树视图,并且需要能够动态添加或删除员工激励线。

<TreeView ItemsSource="{Binding}" Name="MainTree">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding staffincentiveline}">
        <TextBox Text="{Binding name}"/>
        <Button Tag="{Binding}" Click="addline" Content="Add Line" />
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate >
                        <TextBox Text="{Binding lbound}"/>
                        <TextBox Text="{Binding percentage}"/>
                        <Button Tag="{Binding}" Click="delLine" Content="Remove"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

这很好用,但是员工激励线没有排序,但它们确实需要按顺序出现(升序 lbound)。 所以我一直在寻找解决方案并找到了一个转换器

public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
        {return
((EntityCollection<staffincentiveline>)value).OrderBy(o => o.lbound);}

然后我意识到,现在当我使用屏幕上的按钮添加或删除员工奖励热线时,更改不会显示。如果我理解正确,那是因为激励线是通过排序转换器提供的视图显示的,并且在对集合进行更改时视图不会刷新。如果我再次理解正确,这是因为 EntityCollection 没有实现 INotifyPropertyChanged。 如果我使用
刷新视图 CollectionViewSource.GetDefaultView(_incentives).Refresh();然后所有的树视图都被刷新,所有的项目都被折叠起来,这对用户来说是相当混乱的......

那么,如何在不更改对象类 Staffincentive 和 Staffincentiveline 的情况下同时进行排序和刷新工作?我是否应该创建另一个包含它们的类并实现 INotifyPropertyChanged?

谢谢

【问题讨论】:

    标签: c# wpf entity-framework sorting refresh


    【解决方案1】:

    我成功了:)

    我创建了 2 个实现 INotifyPropertyChanged 的​​类 StaffIncentiveHelperObject 和 StaffIncentiveLineHelperObject。当通过访问者进行更改时,它们会与现有类重叠并触发事件。 正如您可以在 StaffIncentiveHelperObject 的 ObservableCollection 中添加/删除 StaffIncentiveLineHelperObject 的方法一样,这些方法还可以从 EDM 中添加/删除原始对象......这是有效链接对视图所做的更改与数据库的位。

    public class StaffIncentiveHelperObject : INotifyPropertyChanged//
        {
            public delegate void CollectionChangedDelegate();
            public static CollectionChangedDelegate CollectionChanged;
    
            public StaffIncentiveHelperObject(staffincentive input)
            {
                this._StaffIncentive = input;
            }
    
    
            private staffincentive _StaffIncentive;
            public staffincentive StaffIncentive
            {
                get { return _StaffIncentive; }
                set
                {
                    if (_StaffIncentive == value) return;
                    _StaffIncentive = value;
                    OnPropertyChanged("StaffIncentive");
                }
            }
    
            public decimal? StaffIncentiveIncrement
            {
                get 
                { 
                    return _StaffIncentive.increment; 
                }
                set
                {
                    if (_StaffIncentive.increment != value)
                    {
                        _StaffIncentive.increment = value;
                        OnPropertyChanged("StaffIncentive");
                    }
                }
            }
    
            public string StaffIncentiveName
            {
                get
                {
                    return _StaffIncentive.name;
                }
                set
                {
                    if (_StaffIncentive.name != value)
                    {
                        _StaffIncentive.name = value;
                        OnPropertyChanged("StaffIncentive");
                    }
                }
            }
    
            public byte? StaffIncentiveType
            {
                get
                {
                    return _StaffIncentive.type;
                }
                set
                {
                    if(_StaffIncentive.type != value)
                    {
                        _StaffIncentive.type = value;
                        OnPropertyChanged("StaffIncentive");
                    }
                }
            }
    
            private ObservableCollection<StaffIncentiveLineHelperObject> _StaffIncentiveLines = new ObservableCollection<StaffIncentiveLineHelperObject>();
            public ObservableCollection<StaffIncentiveLineHelperObject> StaffIncentiveLines
            {
                get { return _StaffIncentiveLines; }
                set { _StaffIncentiveLines = value; OnPropertyChanged("StaffIncentiveLines"); }
            }
    
    
            public void AddStaffIncentiveLine( staffincentiveline SIL)
            {
                SIL.staffincentive = this._StaffIncentive;
                _StaffIncentive.staffincentiveline.Add(SIL);
                StaffIncentiveLines.Add(new StaffIncentiveLineHelperObject(SIL, this));
                //OnPropertyChanged("StaffIncentiveLine");
                if (CollectionChanged != null)
                {
                    CollectionChanged.Invoke();
                }
    
            }
    
            public void RemoveStaffIncentiveLine(StaffIncentiveLineHelperObject SILHO)
            {
                _StaffIncentive.staffincentiveline.Remove(SILHO.StaffIncentiveLine);
                _StaffIncentiveLines.Remove(SILHO);
                //OnPropertyChanged("StaffIncentiveLine");
                if (CollectionChanged != null)
                {
                    CollectionChanged.Invoke();
                }
    
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged(string name)
            {
                var x = PropertyChanged;
                if (x != null)
                    x(this, new PropertyChangedEventArgs(name));
            }
    
            #endregion
        }
    
        public class StaffIncentiveLineHelperObject : INotifyPropertyChanged//, INotifyCo
        {
            public StaffIncentiveLineHelperObject(staffincentiveline input, StaffIncentiveHelperObject parent)
            {
                this._StaffIncentiveLine = input;
                this.Parent = parent;
            }
    
    
            public StaffIncentiveHelperObject Parent { get; set;}
    
            private staffincentiveline _StaffIncentiveLine;
            public staffincentiveline StaffIncentiveLine
            {
                get { return _StaffIncentiveLine; }
                set
                {
                    if (_StaffIncentiveLine == value) return;
                    _StaffIncentiveLine = value;
                    OnPropertyChanged("StaffIncentiveLine");
                }
            }
    
            public decimal? StaffIncentiveLineLbound
            {
                get
                {
                    return _StaffIncentiveLine.lbound;
                }
                set
                {
                    if (_StaffIncentiveLine.lbound != value)
                    {
                        _StaffIncentiveLine.lbound = value;
                        OnPropertyChanged("StaffIncentiveLine");
                    }
                }
            }
    
            public double? StaffIncentiveLinePercentage
            {
                get
                {
                    return _StaffIncentiveLine.percentage;
                }
                set
                {
                    if (_StaffIncentiveLine.percentage != value)
                    {
                        _StaffIncentiveLine.percentage = value;
                        OnPropertyChanged("StaffIncentiveLine");
                    }
                }
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged(string name)
            {
                var x = PropertyChanged;
                if (x != null)
                    x(this, new PropertyChangedEventArgs(name));
    
            }
    
            #endregion
        }
    

    xaml 的 datacontext 设置为 ObservableCollection,它是简单地从 EDM 的现有对象构建的,像这样

    ObservableCollection<SupportingObjects.StaffIncentiveHelperObject> myIcentives = new ObservableCollection<SupportingObjects.StaffIncentiveHelperObject>();
    foreach (staffincentive SI in db_incentives)
    {
        StaffIncentiveHelperObject SIHO = new StaffIncentiveHelperObject(SI);
        myIcentives.Add(SIHO);
        foreach (staffincentiveline SIL in SI.staffincentiveline)
        {
            SIHO.AddStaffIncentiveLine(SIL);
        }
    }
    

    然后 XAML 使用访问器显示/更新它。

    <TreeView ItemsSource="{Binding}" Name="MainTree">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding StaffIncentiveLines, Converter={StaticResource IncentiveLineHelperObjectSort}, ConverterParameter=StaffIncentiveLineLbound}">
            <StackPanel Orientation="Horizontal" >
                <TextBox Text="{Binding StaffIncentiveName}" Width="120" />
                <Button Tag="{Binding}" Click="addline" Content="Add Line" />
            </StackPanel>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate >
                    <StackPanel Orientation="Horizontal"  Margin="150,0,0,0">
                        <TextBox Text="{Binding StaffIncentiveLineLbound, StringFormat='{}{0:c}'}" Width="120" />
                        <TextBox Text="{Binding StaffIncentiveLinePercentage}" Width="120" />
                    <Button Tag="{Binding}" Click="delLine" Content="Remove"/>
                    </StackPanel>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    

    排序仅在第一次加载时完成,而不是在添加行时动态完成,这对我来说很好。这是排序转换器(我从网站上的另一个问题中复制了它)

    public class IncentiveLineHelperObjectSort : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                System.Collections.ObjectModel.ObservableCollection<StaffIncentiveLineHelperObject> collection = value as System.Collections.ObjectModel.ObservableCollection<StaffIncentiveLineHelperObject>;
                ListCollectionView view = new ListCollectionView(collection);
                System.ComponentModel.SortDescription sort = new System.ComponentModel.SortDescription(parameter.ToString(), System.ComponentModel.ListSortDirection.Ascending);
                view.SortDescriptions.Add(sort);
    
                return view;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return null;
            }
        }
    

    这是在按下按钮时添加或删除员工激励线的方法。

    private void addline(object sender, RoutedEventArgs e)
            {
                var incentive = ((sender as Button).Tag as StaffIncentiveHelperObject);
                incentive.AddStaffIncentiveLine(new staffincentiveline());
                TreeViewItem thisTreeViewItem = MainTree.ItemContainerGenerator.ContainerFromItem(incentive) as TreeViewItem;
                thisTreeViewItem.IsExpanded = true;
            }
    
            private void delLine(object sender, RoutedEventArgs e)
            {
                var line = ((sender as Button).Tag as StaffIncentiveLineHelperObject);
                StaffIncentiveHelperObject thisIncentive = line.Parent;
    
                thisIncentive.RemoveStaffIncentiveLine(line);
                TreeViewItem thisTreeViewItem = MainTree.ItemContainerGenerator.ContainerFromItem(thisIncentive) as TreeViewItem;
                if (thisIncentive.StaffIncentiveLines.Count == 0)
                {
    
                    thisTreeViewItem.IsExpanded = false;
                }
            }
    

    如果其他人有更好的方法或改进方法,我很高兴听到它:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 2012-06-29
      • 2020-08-09
      相关资源
      最近更新 更多