简体   繁体   English

当 static ObservableCollection 的元素的属性被修改时更新 UI

[英]Updating UI when a property of an element of a static ObservableCollection is modified

My question has two parts:我的问题有两个部分:

  1. Label content is not updating when using Content="{Binding SelectedPerson.Age}" in xaml instead of SelectedPersonAge.Content = SelectedPerson.Age;在 xaml 中使用Content="{Binding SelectedPerson.Age}"而不是SelectedPersonAge.Content = SelectedPerson.Age; refering to Why binding using ItemsSource is working in code but not in xaml?参考Why binding using ItemsSource is working in code but not in xaml? . . I have set the datacontext and SelectedPerson is a property.我已经设置了datacontext并且SelectedPerson是一个属性。
  2. Even when updating upon combobox item changed (using code behind), when a modification occurs on one of the properties of the selected item label field is not updating, I tried to implement INotifyPropertyChanged but it fires when .add() .delete() .clear() are involved but does not with Peoplelist[0].Age = 5;即使更新ZA8284521647549D6ECBBBBBBBBBBBBBB00383C28BDZ项目更改(在后面使用代码),当对所选项目ZD304BA20E96D874411588EEABAC850EE34Z FIELD的一个属性进行了修改时,我在fires .add() .delete() .clear()参与但不涉及Peoplelist[0].Age = 5; . .

What I am doing wrong?我做错了什么? Is it possible to achieve by simple code without using complicated mvvm external frameworks?不使用复杂的 mvvm 外部框架,是否可以通过简单的代码来实现?

Mainwindow.xaml.cs主窗口.xaml.cs

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfTest
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public ObservableCollection<People> Peoplelist { get; set; } = new ObservableCollection<People>();
        public event PropertyChangedEventHandler PropertyChanged;
        private People _SelectedPerson;

        public People SelectedPerson
        {
            get { return _SelectedPerson; }
            set
            {
                if (value != _SelectedPerson)
                {
                    _SelectedPerson= value;
                    NotifyPropertyChanged("SelectedPerson");
                }
            }
        }

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public MainWindow()
        {
            People.Populate(Peoplelist);

            InitializeComponent();
            DataContext = this;
        }

            private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Modify Jon's Age property while it's selected: not automatically updating in ui
            Peoplelist[0].Age = 5;
        }

        private void combo1_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            SelectedPersonAge.Content = SelectedPerson.Age;  //not working when put in xaml
        }
    }


    public class People : INotifyPropertyChanged
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        private int _Age;
        public int Age
        {
            get { return _Age; }
            set
            {
                _Age = value;
                RaisePropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }


        public People() { }

        public People(String _FirstName, String _FamilyName)
        {
            FirstName = _FirstName;
            LastName = _FamilyName;
            Age = 0;
        }

        public static void Populate(ObservableCollection<People> lst)
        {
            lst.Add(new People
            {
                FirstName = "Jon",
                LastName = "Jonathan",
            });
            lst.Add(new People
            {
                FirstName = "Mark",
                LastName = "Markthan",
            });
            lst.Add(new People
            {
                FirstName = "Spence",
                LastName = "Spencer",
            });
        }
    }
}

MainWindow.xaml主窗口.xaml

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <ComboBox  Name="combo1" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="200" SelectedValuePath="Age" SelectionChanged="combo1_SelectionChanged" ItemsSource="{Binding Path=Peoplelist}" SelectedItem="{Binding SelectedPerson}">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding FirstName}"/>
                            <TextBlock Text="--"/>
                            <TextBlock Text="{Binding LastName}"/>
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <Label Name="SelectedPersonAge" Width="200" Height="35" HorizontalAlignment="center" VerticalAlignment="center" Content="{Binding SelectedPerson.Age}"/>
            <Button Height="35"  Click="Button_Click">
                Test
            </Button>
        </StackPanel>
    </Grid>
</Window>

As @PeterDuniho pointed out in his comment I corrected the DataContext for both controls combobox and label using DataContext="{Binding ElementName=MyWindow} .正如@PeterDuniho 在他的评论中指出的那样,我使用DataContext="{Binding ElementName=MyWindow}更正了两个控件 combobox 和 label 的DataContext

SelectedPersonAge.Content = combo1.SelectedValue; is not required anymore as it is implemented in xaml.不再需要,因为它在 xaml 中实现。

Mainwindow.xaml.cs主窗口.xaml.cs

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfTest
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public ObservableCollection<People> Peoplelist { get; set; } = new ObservableCollection<People>();
        public event PropertyChangedEventHandler PropertyChanged;
        private People _SelectedPerson;

        public People SelectedPerson
        {
            get { return _SelectedPerson; }
            set
            {
                if (value != _SelectedPerson)
                {
                    _SelectedPerson= value;
                    NotifyPropertyChanged("SelectedPerson");
                }
            }
        }

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public MainWindow()
        {
            People.Populate(Peoplelist);

            InitializeComponent();
        }

            private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Modify Jon's Age property while it's selected: not automatically updating in ui
            Peoplelist[0].Age = 5;
        }

        private void combo1_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
        }
    }


    public class People : INotifyPropertyChanged
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        private int _Age;
        public int Age
        {
            get { return _Age; }
            set
            {
                _Age = value;
                RaisePropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }


        public People() { }

        public People(String _FirstName, String _FamilyName)
        {
            FirstName = _FirstName;
            LastName = _FamilyName;
            Age = 0;
        }

        public static void Populate(ObservableCollection<People> lst)
        {
            lst.Add(new People
            {
                FirstName = "Jon",
                LastName = "Jonathan",
            });
            lst.Add(new People
            {
                FirstName = "Mark",
                LastName = "Markthan",
            });
            lst.Add(new People
            {
                FirstName = "Spence",
                LastName = "Spencer",
            });
        }
    }
}

MainWindow.xaml主窗口.xaml

<Window x:Class="WpfTest.MainWindow" x:Name="MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <ComboBox  Name="combo1" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="200" SelectedValuePath="Age" SelectionChanged="combo1_SelectionChanged" ItemsSource="{Binding Path=Peoplelist}" SelectedItem="{Binding SelectedPerson}" DataContext="{Binding ElementName=MyWindow}">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding FirstName}"/>
                            <TextBlock Text="--"/>
                            <TextBlock Text="{Binding LastName}"/>
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <Label Name="SelectedPersonAge" Width="200" Height="35" HorizontalAlignment="center" VerticalAlignment="center" Content="{Binding SelectedPerson.Age}" DataContext="{Binding ElementName=MyWindow}"/>
            <Button Height="35"  Click="Button_Click">
                Test
            </Button>
        </StackPanel>
    </Grid>
</Window>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在ObservableCollection中更改模型属性时更新UI? - Updating UI when a model property changes in an ObservableCollection? 在另一个View中修改ObservableCollection时,组合框未更新 - ComboBox not updating when ObservableCollection is modified in another View 静态属性未在UI中更新 - Static property not updating in UI Winui3 桌面; ObservableCollection,在属性更改时更新 UI? 从不同线程更新 - Winui3 Desktop; ObservableCollection, updating UI when property changes? Updating from different thread 的ObservableCollection <DateTime> 并在项目更改时更新用户界面 - ObservableCollection<DateTime> and updating the UI when the item changes 更改ObservableCollection的内容时难以更新UI? - Difficulty updating UI when contents of ObservableCollection is changed? 调用add时,ObservableCollection依赖项属性未更新 - ObservableCollection dependency property not updating when add is called Observablecollection在更新属性时更新多个项目 - Observablecollection updates multiple items when updating a property 属性更改时,ObservableCollection未更新为UI - ObservableCollection not updated to UI when property changed 修改项目的属性时提高ObservableCollection中的CollectionChanged - Raise CollectionChanged in ObservableCollection when an item's property is modified
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM