【问题标题】:Explicit UpdateSource on element with LostFocus trigger带有 LostFocus 触发器的元素上的显式 UpdateSource
【发布时间】:2026-01-21 12:30:01
【问题描述】:

我的场景是,在打开应用程序时,我从文件中读取大量数据(使用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();
}

【问题讨论】:

    标签: c# wpf binding updatesourcetrigger


    【解决方案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

    当我修改那里的值并单击保存按钮时,我可以看到发生了什么,在 Save 方法中有一个断点并且值被更新,因为当您单击按钮时, TextBox 失去焦点。

    无论如何我想写给你,因为可能还有更多。

    看看IEditableObject接口:

    提供提交或回滚对对象的更改的功能 用作数据源。

    就是这样。

    【讨论】:

      最近更新 更多