[英]Changes to ObservableCollection from UI not updating the Bound Collection
In XAML I have a list view: 在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://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>
The Corresponding UI looks like this: 对应的UI如下所示:
On Click of an Add button I add an Empty row as follows : 单击添加按钮我添加一个空行,如下所示:
I Enter text into the text boxes. 我在文本框中输入文本。 The change made to the listview by entering text in the textbox is not updating the observableCollection to which the textboxes are bound.
通过在文本框中输入文本对列表视图所做的更改不会更新文本框绑定到的observableCollection。
The class of the observable collection is as below : 可观察集合的类如下:
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));
}
}
By editing the text in the textboxes you do not change the ObservableCollection
but you change one of the objects inside the collection. 通过编辑文本框中的文本,您不会更改
ObservableCollection
但可以更改集合中的一个对象。 The collection is not aware of changing the internal(!) state of one the objects in it. 该集合不知道更改其中一个对象的内部(!)状态。 Those changes can be captured by the
PropertyChanged
event of your ConfigObject
class. ConfigObject
类的PropertyChanged
事件可以捕获这些更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.