我有一个ListBox
,其ItemSource
绑定到ObservableCollection
。 ListBox
具有以下(最小化)ItemTemplate
:
<ListBox ItemsSource="{Binding SelectedDirectory.PluginValues}" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid Height="29" Margin="5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Width="Auto"
Text="{Binding Name, Mode=TwoWay
, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="1" Width="Auto"
Text="{Binding Value, Mode=TwoWay
, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
绑定选项UpdateSourceTrigger=PropertyChanged
会导致TextBoxes
在每次按键到周围ListBox
后失去焦点。当我删除该选项时,焦点不会丢失,但TextBox
中的值不会立即保存到属性中。因此,当我输入一个值然后提出一个命令(例如通过保存Button
)时,该属性不会更新。只有当我先点击其他地方然后再提高命令时,值才会更新。
修改
简化的ViewModel:
public class ViewModel : INotifyPropertyChanged
{
private FbiDirectory selectedDirectory;
public FbiDirectory SelectedDirectory
{
get
{
return this.selectedDirectory;
}
set
{
this.selectedDirectory = value;
this.OnPropertyChanged("SelectedDirectory");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
FbiDirectory类(与联邦调查局无关):
public class FbiDirectory : INotifyPropertyChanged
{
private ObservableCollection<PluginValue> pluginValues = new ObservableCollection<PluginValue>();
public ObservableCollection<PluginValue> PluginValues
{
get
{
return this.pluginValues;
}
set
{
this.pluginValues = value;
this.OnPropertyChanged("PluginValues");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
PluginValue类:
public class PluginValue : INotifyPropertyChanged
{
private string name;
private string value;
public string Name
{
get => name;
set
{
name = value;
this.OnPropertyChanged("Name");
}
}
public string Value
{
get => value;
set
{
this.value = value;
this.OnPropertyChanged("Value");
}
}
public PluginValue(string name, string value)
{
this.Name = name;
this.Value = value;
}
public PluginValue()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
答案 0 :(得分:0)
您问题的简化代码可能如下所示:
public class MyViewModel
{
public ObservableCollection<ItemViewModel> Items { get; set; }
public ICommand SaveCommand { get; }
public MyViewModel()
{
SaveCommand = new RelayCommand(OnSaveCommand);
Items = new ObservableCollection<ItemViewModel>();
Items.Add(new ItemViewModel{Name = "test1", Value = "test1"});
Items.Add(new ItemViewModel{Name = "test2", Value = "test2"});
}
private void OnSaveCommand()
{
var message = Items.Aggregate(new StringBuilder(),
(builder, item) => builder.AppendLine($"{item.Name} {item.Value}"));
message.AppendLine("Will be save");
MessageBox.Show(message.ToString());
}
}
public class ItemViewModel : NotifiableObject
{
private string _value;
private string _name;
public string Name
{
get => _name;
set
{
OnPropertyChanged();
_name = value;
}
}
public string Value
{
get => _value;
set
{
OnPropertyChanged();
_value = value;
}
}
}
public class NotifiableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
有了这个观点:
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Items}" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid Height="29" Margin="5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="1" Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Content="Save" Command="{Binding SaveCommand}"></Button>
</Grid>
不确定代码中的错误,但是:
希望它有所帮助。