[英]Updating UI when a property of an element of a static ObservableCollection is modified
My question has two parts:我的问题有两个部分:
Content="{Binding SelectedPerson.Age}"
in xaml instead of SelectedPersonAge.Content = SelectedPerson.Age;
Content="{Binding SelectedPerson.Age}"
而不是SelectedPersonAge.Content = SelectedPerson.Age;
refering to Why binding using ItemsSource is working in code but not in xaml?datacontext
and SelectedPerson
is a property.datacontext
并且SelectedPerson
是一个属性。.add()
.delete()
.clear()
are involved but does not with Peoplelist[0].Age = 5;
.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.