簡體   English   中英

當 static ObservableCollection 的元素的屬性被修改時更新 UI

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

我的問題有兩個部分:

  1. 在 xaml 中使用Content="{Binding SelectedPerson.Age}"而不是SelectedPersonAge.Content = SelectedPerson.Age; 參考Why binding using ItemsSource is working in code but not in xaml? . 我已經設置了datacontext並且SelectedPerson是一個屬性。
  2. 即使更新ZA8284521647549D6ECBBBBBBBBBBBBBB00383C28BDZ項目更改(在后面使用代碼),當對所選項目ZD304BA20E96D874411588EEABAC850EE34Z FIELD的一個屬性進行了修改時,我在fires .add() .delete() .clear()參與但不涉及Peoplelist[0].Age = 5; .

我做錯了什么? 不使用復雜的 mvvm 外部框架,是否可以通過簡單的代碼來實現?

主窗口.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",
            });
        }
    }
}

主窗口.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>

正如@PeterDuniho 在他的評論中指出的那樣,我使用DataContext="{Binding ElementName=MyWindow}更正了兩個控件 combobox 和 label 的DataContext

SelectedPersonAge.Content = combo1.SelectedValue; 不再需要,因為它在 xaml 中實現。

主窗口.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",
            });
        }
    }
}

主窗口.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM