C# 从UI对ObservableCollection的更改未更新绑定集合
在XAML中,我有一个列表视图:C# 从UI对ObservableCollection的更改未更新绑定集合,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,在XAML中,我有一个列表视图: <UserControl x:Class="HspSetup.View.UserInputData" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://sc
<UserControl x:Class="HspSetup.View.UserInputData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HspSetup.View"
xmlns:viewModel="clr-namespace:HspSetup.ViewModel"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Behaviours="clr-namespace:HspSetup.Behaviours"
mc:Ignorable="d"
Height="Auto" Width="Auto">
<UserControl.Resources>
<viewModel:UserInputDataViewModel x:Key="ViewModel"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<TextBlock Background="Coral" Height="50"
VerticalAlignment="Center" TextAlignment="Center"
Grid.Row="0" Grid.ColumnSpan="3">
<TextBlock.Text>Some More Data</TextBlock.Text>
<TextBlock.FontFamily>Segoe UI</TextBlock.FontFamily>
<TextBlock.Foreground>White</TextBlock.Foreground>
<TextBlock.FontSize>30</TextBlock.FontSize>
</TextBlock>
<ListView Grid.Row="2" Width="Auto"
Behaviours:GridViewColumnResize.Enabled="True"
Height="Auto" Name="OrderNumberListView"
IsSynchronizedWithCurrentItem="True" Grid.Column="1"
DataContext="{Binding Source={StaticResource ViewModel}}"
ItemsSource="{Binding ConfigObjects}" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="Behaviours:LostFocus.LostFocusCommand"
Value="{Binding Path=LostFocusCommand, Source={StaticResource ViewModel}}"/>
<Setter Property="Behaviours:LostFocus.CommandParem"
Value="{Binding}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Order Name"
Behaviours:GridViewColumnResize.Width="*">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding OrderNumber, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource flatTextBox}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Type Name"
Behaviours:GridViewColumnResize.Width="*">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding TypeName, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource flatTextBox}">
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Behaviours:GridViewColumnResize.Width="*" >
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<Button Content="Add"
Command="{Binding AddConfigObjectCommand, Mode=OneWay, Source={StaticResource ViewModel}}"/>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumnHeader HorizontalContentAlignment="Stretch"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Name="RemoveButton"
Content="Remove"
Command="{Binding RemoveConfigObjectCommand, Mode=OneWay, Source={StaticResource ViewModel}}" CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>
更多数据
微软雅黑效果
白色
30
相应的UI如下所示:
单击“添加”按钮后,我添加一个空行,如下所示:
我在文本框中输入文本。
通过在文本框中输入文本对listview所做的更改不会更新文本框绑定到的observableCollection
可观测集合的类别如下所示:
class UserInputDataViewModel: BaseViewModel
{
private ObservableCollection<ConfigObject> _configObjects;
public ObservableCollection<ConfigObject> ConfigObjects
{
get { return _configObjects; }
set
{
_configObjects = value;
OnPropertyChanged("ConfigObjects");
}
}
private ICommand _addConfigObject;
public ICommand AddConfigObjectCommand
{
get
{
if (_addConfigObject == null)
{
_addConfigObject = new RelayCommand(
p => AddConfigObject(),
p => CanAddConfigObject);
}
return _addConfigObject;
}
}
private void AddConfigObject()
{
ConfigObjects.Add(new ConfigObject() { OrderNumber = "", TypeName = "" });
OnPropertyChanged("ConfigObjects");
}
private ICommand _removeConfigObject;
public ICommand RemoveConfigObjectCommand
{
get
{
if (_removeConfigObject == null)
{
_removeConfigObject = new RelayCommand(
p => RemoveConfigObject((ConfigObject)p),
p => CanRemoveConfigObject);
}
return _removeConfigObject;
}
}
private void RemoveConfigObject(ConfigObject configObject)
{
ConfigObjects.Remove(configObject);
OnPropertyChanged("ConfigObjects");
}
bool CanAddConfigObject
{
get { return true; }
}
bool CanRemoveConfigObject
{
get { return true; }
}
}
class BaseViewModel:INotifyPropertyChanged
{
/// <summary>
/// Name of the property that changed
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Send the notification to the property that change
/// </summary>
/// <param name="pPropertyName">name of the property</param>
protected virtual void OnPropertyChanged(string pPropertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this,
new PropertyChangedEventArgs(pPropertyName));
}
}
}
internal class ConfigObject : INotifyPropertyChanged
{
private string _orderNumber;
public string OrderNumber
{
get { return _orderNumber; }
set { _orderNumber = value; OnPropertyChanged("OrderNumber"); }
}
private string _typeName;
public string TypeName
{
get { return _typeName; }
set { _typeName = value; OnPropertyChanged("TypeName"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string paramname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(paramname));
}
}
类UserInputDataViewModel:BaseViewModel
{
私有ObservableCollection\u配置对象;
公共ObservableCollection配置对象
{
获取{return\u configObjects;}
设置
{
_配置对象=值;
OnPropertyChanged(“配置对象”);
}
}
私有ICommand_addConfigObject;
公共ICommand AddConfigObjectCommand
{
得到
{
如果(_addConfigObject==null)
{
_addConfigObject=new RelayCommand(
p=>AddConfigObject(),
p=>CanadConfigObject);
}
返回_addConfigObject;
}
}
私有void AddConfigObject()
{
添加(新的ConfigObject(){OrderNumber=“”,TypeName=“”});
OnPropertyChanged(“配置对象”);
}
私有ICommand_removeConfigObject;
公共ICommand RemoveConfigObjectCommand
{
得到
{
如果(_removeConfigObject==null)
{
_removeConfigObject=新的RelayCommand(
p=>RemoveConfigObject((ConfigObject)p),
p=>CanRemoveConfigObject);
}
返回removeConfigObject;
}
}
私有void RemoveConfigObject(ConfigObject ConfigObject)
{
ConfigObjects.Remove(configObject);
OnPropertyChanged(“配置对象”);
}
布尔CanAddConfigObject
{
获取{return true;}
}
布尔CanRemoveConfigObject
{
获取{return true;}
}
}
类BaseViewModel:INotifyPropertyChanged
{
///
///更改的属性的名称
///
公共事件属性更改事件处理程序属性更改;
///
///向更改的属性发送通知
///
///物业名称
受保护的虚拟void OnPropertyChanged(字符串PPPropertyName)
{
if(this.PropertyChanged!=null)
{
这个。财产改变了(这个,
新属性ChangedEventArgs(PPPropertyName));
}
}
}
内部类ConfigObject:INotifyPropertyChanged
{
私有字符串_orderNumber;
公共字符串顺序号
{
获取{return\u orderNumber;}
设置{u orderNumber=value;OnPropertyChanged(“orderNumber”);}
}
私有字符串_typeName;
公共字符串类型名
{
获取{return\u typeName;}
set{u typeName=value;OnPropertyChanged(“typeName”);}
}
公共事件属性更改事件处理程序属性更改;
私有void OnPropertyChanged(字符串参数名)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(paramname));
}
}
通过编辑文本框中的文本,您不会更改
可观察集合
,但会更改集合中的一个对象。集合不知道更改其中一个对象的内部(!)状态。您的ConfigObject
类的PropertyChanged
事件可以捕获这些更改。谢谢您的回答。但是您可以看到,我已经在ConfigObject类中实现了INontifyPropertyChanged接口。我对收藏中的物品所做的更改仍然不可见。你说“不可见”是什么意思?您希望在哪里看到它?我的意思是,尽管我对ConfigObject
类的每个属性调用了OnpropertyChanged
方法,但集合没有更新。你能告诉我在用户输入文本时更新集合所缺少的代码吗?实际上集合中没有任何更改。编辑文本框后,更改的对象将出现在您的集合中。你只是没有收到通知。ConfigObject中的PropertyChanged用于更新UI绑定,而不是我理解的CollectionKay。现在,我需要做什么才能获得更新的集合,以便在稍后获取集合时,我能够看到集合项中的UI所做的更改。感谢您的编辑Emo de Weerd先生。这将非常有帮助