Явный UpdateSource для элемента с триггером LostFocus
Мой сценарий, при открытии приложения, я читаю много данных из файла (используя XMLSerializer
) и положить его в ObservableCollection<MyClass>
, Используя привязки, я представляю данные пользователям. Когда они изменяют данные в поле, соответствующие данные в коллекции обновляются, но я не хочу, чтобы эти данные были сохранены в файл при LostFocus
, У меня есть кнопка "Сохранить".
Я не хочу использовать UpdateSOurceTrigger = PropertyChanged
Хочу сохранить LostFocus
, Проблема в том, что когда пользователь вводит данные в TextBox
и нажимает кнопку Сохранить, TextBox
не теряет фокус, то есть данные не передаются в коллекцию и не сохраняются. Ниже мое решение, которое работает, но мой вопрос таков: это правильный путь или есть другой, лучший способ?
Код, который я добавил к кнопке Сохранить, перед сохранением коллекции:
IInputElement focusedElement = Keyboard.FocusedElement;
if (focusedElement is TextBox)
{
BindingExpression myBinding = BindingOperations.GetBindingExpression((TextBox)focusedElement, TextBox.TextProperty);
myBinding.UpdateSource();
}
1 ответ
Вот небольшой пример вашего сценария:
<Window x:Class="MementoAndLostFocus.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"
xmlns:local="clr-namespace:MementoAndLostFocus"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Text="{Binding ExampleInstance.ExampleName, UpdateSourceTrigger=LostFocus}"
BorderThickness="1"
BorderBrush="Black"
VerticalAlignment="Top"
Margin="10"/>
<Button Grid.Row="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="Save"
Command="{Binding SaveCommand}"/>
</Grid>
public class MainViewModel
{
public ExampleClass ExampleInstance { get; set; }
public ICommand SaveCommand { get; set; }
public MainViewModel()
{
ExampleInstance = new ExampleClass() { ExampleName = "Example Name" };
SaveCommand = new SaveCommand(this);
}
internal void Save()
{
//TO DO - Save item to database
Console.WriteLine(ExampleInstance.ExampleName);
}
}
public class ExampleClass : INotifyPropertyChanged
{
private string _exampleName;
public string ExampleName
{
get { return _exampleName; }
set
{
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ExampleName)));
_exampleName = value;
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
public class SaveCommand : ICommand
{
private MainViewModel _vm;
public event EventHandler CanExecuteChanged;
public SaveCommand(MainViewModel vm)
{
_vm = vm;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_vm.Save();
}
}
Итак, что именно здесь происходит:
Как видите, TextBox
там и его UpdateSourceTrigger
установлен в LostFocus
,
Когда я изменяю значение и нажимаю кнопку "Сохранить", я вижу, что происходит, с точкой останова в методе "Сохранить", и значение обновляется, поскольку при нажатии кнопкиTextBox
теряет фокус
Во всяком случае, я хотел написать это для вас, потому что может быть что-то еще.
Посмотри на IEditableObject
интерфейс:
Предоставляет функциональность для фиксации или отката изменений объекта, который используется в качестве источника данных.
Вот и все.