【问题标题】:Update a listview from modify on selected items从修改选定项目更新列表视图
【发布时间】:2017-12-08 07:50:01
【问题描述】:

对不起,如果我没有很好地提出这个问题,但不知道如何更好地命名它......

我有一个包含一些 ListView 的项目,绑定到 ObservableCollection。 当我右键单击我的 ListView 以更改名称或其他参数时,ListView 不会自动刷新,直到我出去,然后再次打开。

这是我的上下文代码:

public class Contexte : INotifyPropertyChanged
    {
        private Affaire affaireSelectionnee;
        public Affaire AffaireSelectionnee
        {
            get { return affaireSelectionnee; }
            set
            {
                if (value == affaireSelectionnee) return;
                affaireSelectionnee = value;
                NotifyPropertyChanged("AffaireSelectionnee");
            }
        }

        private ObservableCollection<Affaire> listeDesAffairesSelectionnees;
        public ObservableCollection<Affaire> ListeDesAffairesSelectionnees
        {
            get { return listeDesAffairesSelectionnees; }
            set { NotifyPropertyChanged(ref listeDesAffairesSelectionnees, value); }
        }
        private ObservableCollection<Phase> listeDesPhasesSelectionnees;
        public ObservableCollection<Phase> ListeDesPhasesSelectionnees
        {
            get { return listeDesPhasesSelectionnees; }
            set { NotifyPropertyChanged(ref listeDesPhasesSelectionnees, value); }
        }
        private ObservableCollection<Assemblage> listeDesAssemblagesSelectionnees;
        public ObservableCollection<Assemblage> ListeDesAssemblagesSelectionnees
        {
            get { return listeDesAssemblagesSelectionnees; }
            set { NotifyPropertyChanged(ref listeDesAssemblagesSelectionnees, value); }
        }
        private ObservableCollection<Repere> listeDesReperesSelectionnees;
        public ObservableCollection<Repere> ListeDesReperesSelectionnees
        {
            get { return listeDesReperesSelectionnees; }
            set { NotifyPropertyChanged(ref listeDesReperesSelectionnees, value); }
        }

        private ObservableCollection<Affaire> listeDesAffaires;
        public ObservableCollection<Affaire> ListeDesAffaires
        {
            get { return listeDesAffaires; }
            set { NotifyPropertyChanged(ref listeDesAffaires, value); }
        }
        private ObservableCollection<Phase> listeDesPhases;
        public ObservableCollection<Phase> ListeDesPhases
        {
            get { return listeDesPhases; }
            set { NotifyPropertyChanged(ref listeDesPhases, value); }
        }
        private ObservableCollection<Assemblage> listeDesAssemblages;
        public ObservableCollection<Assemblage> ListeDesAssemblages
        {
            get { return listeDesAssemblages; }
            set { NotifyPropertyChanged(ref listeDesAssemblages, value); }
        }
        private ObservableCollection<Repere> listeDesReperes;
        public ObservableCollection<Repere> ListeDesReperes
        {
            get { return listeDesReperes; }
            set { NotifyPropertyChanged(ref listeDesReperes, value); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string nomPropriete)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete));
        }

        private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
        {
            if (object.Equals(variable, valeur)) return false;

            variable = valeur;
            NotifyPropertyChanged(nomPropriete);
            return true;
        }

    }

我在加载程序时加载了一次上下文:

DBConnect DataBase = new DBConnect();
string requete = "SELECT * FROM affaire ORDER BY ID";
List<Affaire> liste = DataBase.Select_affaire(requete, true);
contexte = new Contexte { ListeDesAffaires = new ObservableCollection<Affaire>(liste), ListeDesPhases = new ObservableCollection<Phase>(), ListeDesAssemblages = new ObservableCollection<Assemblage>(), ListeDesReperes = new ObservableCollection<Repere>(), AffaireSelectionnee = new Affaire(), ListeDesAffairesSelectionnees = new ObservableCollection<Affaire>(liste), ListeDesPhasesSelectionnees = new ObservableCollection<Phase>(), ListeDesAssemblagesSelectionnees = new ObservableCollection<Assemblage>(), ListeDesReperesSelectionnees = new ObservableCollection<Repere>() };
DataContext = contexte;

然后我的函数可能会更新属性:

foreach (Phase ph in contexte.ListeDesPhasesSelectionnees)
{
  Phase ph_find = contexte.ListeDesPhases.First(s=>s==ph);
  ph_find.Priorite = new_priorite;
}

ph_find.Priorite 更新得很好,我的 Observable Collection "contexte.ListeDesPhases" 也是如此,但 ListView 上没有刷新。

编辑:好吧,我可以解决添加 ListView1.Items.Refresh() 的问题... 我不确定这是最正确的方法(不应该出价自动刷新列表视图吗?),但现在它可以工作

编辑2

我的 XAML 代码(阶段的 ListView):

<ListView x:Name="ListView2" ItemsSource="{Binding ListeDesPhases}" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" MouseDoubleClick="ListView_MouseDoubleClick" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" SelectionChanged="ListView_SelectionChanged" >

            <ListView.View>

                <GridView AllowsColumnReorder="true" x:Name="GridView2">
                    <GridViewColumn DisplayMemberBinding="{Binding ID}" Header="ID" Width="50"/>
                    <GridViewColumn DisplayMemberBinding= "{Binding NomPhase}" Header="{x:Static p:Resources.Nom}" Width="200"/>
                    <GridViewColumn DisplayMemberBinding="{Binding IdAffaire}" Header="{x:Static p:Resources.IdAffaire}" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding CommPhase}" Header="{x:Static p:Resources.Commentaire}" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Priorite}" Header="{x:Static p:Resources.Priorite}" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>

我的阶段课程:

public class Phase
    {
        public string NomPhase { get; set; }
        public long IdAffaire { get; set; }
        public string CommPhase { get; set; }
        public int Priorite { get; set; }
        public long ID { get; set; }
        public List<Assemblage> ListAssemblages { get; set; }
        public Phase()
        {
            this.NomPhase = "";
            this.IdAffaire = 0;
            this.CommPhase = "";
            this.Priorite = 0;
            this.ID = 0;
            this.ListAssemblages = new List<Assemblage>();
        }
        ...
    }

编辑3

尝试按照 Netstep 的指示进行修改,但还是一样:

public ObservableCollection<Phase> ListeDesPhases
        {
            get { return listeDesPhases; }
            set { NotifyPropertyChanged(ref listeDesPhases, value);
                NotifyPropertyChanged("Priorite");
            }
        }

编辑 4

好吧,我现在明白什么都没发生,我读了那门课程http://www.wpf-tutorial.com/data-binding/responding-to-changes/ 来理解它...... 所以NetStep给出的例子很好(只是不明白RaisePropertyChanged(() =&gt; Priorite);部分是什么?这是由于使用了mvvmlight.net库吗?

public class Phase : INotifyPropertyChanged
    {
        private string nomPhase;
        public string NomPhase
        {
            get { return this.nomPhase; }
            set
            {
                if (this.nomPhase != value)
                {
                    this.nomPhase = value;
                    this.NotifyPropertyChanged("NomPhase");
                }
            }
        }
        private int priorite;
        public int Priorite
        {
            get { return this.priorite; }
            set
            {
                if (this.priorite != value)
                {
                    this.priorite = value;
                    this.NotifyPropertyChanged("Priorite");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    ...//all of my other functions
    }

这就是我所做的,现在效果很好。

然后我有以下问题:我在 4 个 ListView(合同、分包合同、阶段和细节)中显示了 4 个不同的对象。 Contract 是“母类”,它包含参数,还包含一个 Subcontracts 列表。 Subcontracts 包含几个参数和一个 Phases 列表,每个 Phase 包含一些参数,以及一个 Details 列表。 它们中的每一个都显示在不同的 ListView(4 ListView) 中。 我可以定义 4 个不同的 ObservableCollection,还是有办法为所有“树”只定义一个 ObservableCollection,然后绑定我的 ObservableCollection 的参数>?

【问题讨论】:

    标签: c# listview observablecollection


    【解决方案1】:

    要在 UI 中正确更新该字段,请确保 Phase 类也以某种方式实现 INotifyPropertyChanged 并调用

    NotifyPropertyChanged("Priorite")
    

    在 set 访问器中。仅使用 ObservableCollection 是不够的,它只处理通知添加/删除操作。你是对的 - ListView1.Items.Refresh() 在这种情况下是一种解决方法。 希望这会有所帮助,否则请分享 Phase 类代码和您的 xaml 代码以获得更清晰的评论/答案。

    以下是基于 MVVM 光库的示例:

    using GalaSoft.MvvmLight;
    
    namespace WpfApp1
    {
        public class Phase : ViewModelBase
        {
            private int _priorite;
    
            public int Priorite
            {
                get { return _priorite; }
                set
                {
                    _priorite = value;
                    RaisePropertyChanged(() => Priorite);
                }
            }
        }
    }
    

    所有其余代码都可以保持不变。你也可以从 ViewModelBase 继承你的 Context 类

    【讨论】:

    • 感谢您的回答,您的意思是我可以为我显示的类的每个属性添加一个“NotifyPropertyChanged”吗?你为什么要参加 Phase 课程?我在一个单独的 Context 类中定义了我所有的 ObservableCollections(或者这也是一种不好的工作模式)。我在使用 ObservableCollection 方面是全新的,所以我不知道如何构建它......
    • 另外,我的foreach(contexte.ListeDesPhasesSelectionnees 中的Phase ph)是最“最佳”的方式,还是有类似“contexte.ListeDesPhases.Find(s =>s==ListeDesPhasesSelectionnees) 一次返回所有选定项目的列表,没有找到任何关于它的信息。还想知道我是否可以制作 2 个不同的 ObservableCollection,一个用于所有列表,一个用于选定项目.. . 当我选择一个项目时,我只需要选择的项目(如果 selectedItems.Count==1),在文本框中显示值。
    • 更好地理解为什么需要 Class...我阅读了很多关于它的内容,但它似乎比绑定从列表中添加/删除对象要困难得多。如果你能给我举个例子,如何修改“属性”值的类,我可以为剩余的属性做这件事(现在没能做到)。
    • 首先,最好为所有将实现 NotifyPropertyChanged 的​​视图模型定义一个基类,或者更好的是使用 MVVM 库,例如 mvvmlight.net,并继承所有视图模型来自基类 ViewModelBase - 我将编辑我的答案并添加一个示例
    • 对于“Phase : ViewModelBase”类,我可以修改我已经创建的类吗,或者这可能是上下文类的一部分?因为我的 Phase 类有很多不交互的功能带视图,如果我理解得很好,ViewModel 可能会与其余代码分开。
    猜你喜欢
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2021-04-16
    相关资源
    最近更新 更多