保存前WPF数据绑定 [英] WPF Databind Before Saving

查看:140
本文介绍了保存前WPF数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WPF应用程序中,我有一些数据绑定的文本框。这些绑定的 UpdateSourceTrigger LostFocus 。使用文件菜单保存对象。我遇到的问题是可以在TextBox中输入一个新值,从File菜单中选择Save,并且永远不会保留新值(TextBox中可见的值),因为访问菜单不会从TextBox中删除焦点。如何解决这个问题?有没有办法强制一个页面中的所有控件进行数据绑定?



@palehorse:好点。不幸的是,我需要使用LostFocus作为我的UpdateSourceTrigger来支持我想要的验证类型。



@dmo:我曾想过那。然而,似乎对于一个相对简单的问题来说,这是一个非常不方便的解决方案。此外,它要求在页面上存在一些可以接收焦点的控件。但是,我的应用程序是标签的,所以没有这样的控件容易呈现。



@Nidonocu:使用菜单没有移动焦点从TextBox也混淆了我。那就是我所看到的行为。以下简单示例演示了我的问题:

 < Window x:Class = WpfApplication2.Window1
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft.com/winfx / 2006 / xaml
Title =Window1Height =300Width =300>
< Window.Resources>
< ObjectDataProvider x:Key =MyItemProvider/>
< /Window.Resources>
& DockPanel LastChildFill =True>
< Menu DockPanel.Dock =Top>
< MenuItem Header =File>
< MenuItem Header =保存Click =MenuItem_Click/>
< / MenuItem>
< / Menu>
< StackPanel DataContext ={Binding Source = {StaticResource MyItemProvider}}>
< Label Content =输入一些文本,然后输入文件>保存:/>
< TextBox Text ={Binding ValueA}/>
< TextBox Text ={Binding ValueB}/>
< / StackPanel>
< / DockPanel>
< / Window>



  using System; 
使用System.Text;
使用System.Windows;
使用System.Windows.Data;

命名空间WpfApplication2
{
public partial class Window1:Window
{
public MyItem Item
{
get {return FindResource(MyItemProvider)为ObjectDataProvider).ObjectInstance为MyItem; }
set {(FindResource(MyItemProvider)作为ObjectDataProvider).ObjectInstance = value; }
}

public Window1()
{
InitializeComponent();
Item = new MyItem();
}

private void MenuItem_Click(object sender,RoutedEventArgs e)
{
MessageBox.Show(string.Format(在保存时,文本框是:\\\
'{0}'\\\
and\\\
'{1}',Item.ValueA,Item.ValueB));
}
}

public class MyItem
{
public string ValueA {get;组; }
public string ValueB {get;组; }
}
}


解决方案


假设您在一个窗口中有一个TextBox,并在其中有一个保存按钮的工具栏。假设TextBox的Text属性绑定到业务对象上的一个属性,并且绑定的UpdateSourceTrigger属性设置为LostFocus的默认值,这意味着当TextBox丢失输入焦点时,绑定值将被推回到业务对象属性。另外,假设ToolBar的Save按钮的Command属性设置为ApplicationCommands.Save命令。



在这种情况下,如果您编辑TextBox并单击鼠标保存按钮,则会出现问题。当单击ToolBar中的Button时,TextBox不会失去焦点。由于TextBox的LostFocus事件不触发,Text属性绑定不会更新业务对象的源属性。



显然,如果UI中最近编辑的值尚未被推入对象,那么您不应该验证并保存对象。这是Karl解决的确切问题,通过在他的窗口中编写代码,手动查找具有焦点的TextBox,并更新了数据绑定的来源。他的解决方案工作正常,但它让我想到一个通用的解决方案,在这种情况之外也是有用的。输入CommandGroup ...


取自Josh Smith的CodeProject文章,关于 CommandGroup


In my WPF application, I have a number of databound TextBoxes. The UpdateSourceTrigger for these bindings is LostFocus. The object is saved using the File menu. The problem I have is that it is possible to enter a new value into a TextBox, select Save from the File menu, and never persist the new value (the one visible in the TextBox) because accessing the menu does not remove focus from the TextBox. How can I fix this? Is there some way to force all the controls in a page to databind?

@palehorse: Good point. Unfortunately, I need to use LostFocus as my UpdateSourceTrigger in order to support the type of validation I want.

@dmo: I had thought of that. It seems, however, like a really inelegant solution for a relatively simple problem. Also, it requires that there be some control on the page which is is always visible to receive the focus. My application is tabbed, however, so no such control readily presents itself.

@Nidonocu: The fact that using the menu did not move focus from the TextBox confused me as well. That is, however, the behavior I am seeing. The following simple example demonstrates my problem:

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <ObjectDataProvider x:Key="MyItemProvider" />
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="File">
                <MenuItem Header="Save" Click="MenuItem_Click" />
            </MenuItem>
        </Menu>
        <StackPanel DataContext="{Binding Source={StaticResource MyItemProvider}}">
            <Label Content="Enter some text and then File > Save:" />
            <TextBox Text="{Binding ValueA}" />
            <TextBox Text="{Binding ValueB}" />
        </StackPanel>
    </DockPanel>
</Window>

using System;
using System.Text;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication2
{
    public partial class Window1 : Window
    {
        public MyItem Item
        {
            get { return (FindResource("MyItemProvider") as ObjectDataProvider).ObjectInstance as MyItem; }
            set { (FindResource("MyItemProvider") as ObjectDataProvider).ObjectInstance = value; }
        }

        public Window1()
        {
            InitializeComponent();
            Item = new MyItem();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("At the time of saving, the values in the TextBoxes are:\n'{0}'\nand\n'{1}'", Item.ValueA, Item.ValueB));
        }
    }

    public class MyItem
    {
        public string ValueA { get; set; }
        public string ValueB { get; set; }
    }
}

解决方案

Suppose you have a TextBox in a window, and a ToolBar with a Save button in it. Assume the TextBox’s Text property is bound to a property on a business object, and the binding’s UpdateSourceTrigger property is set to the default value of LostFocus, meaning that the bound value is pushed back to the business object property when the TextBox loses input focus. Also, assume that the ToolBar’s Save button has its Command property set to ApplicationCommands.Save command.

In that situation, if you edit the TextBox and click the Save button with the mouse, there is a problem. When clicking on a Button in a ToolBar, the TextBox does not lose focus. Since the TextBox’s LostFocus event does not fire, the Text property binding does not update the source property of the business object.

Obviously you should not validate and save an object if the most recently edited value in the UI has not yet been pushed into the object. This is the exact problem Karl had worked around, by writing code in his window that manually looked for a TextBox with focus and updated the source of the data binding. His solution worked fine, but it got me thinking about a generic solution that would also be useful outside of this particular scenario. Enter CommandGroup…

Taken from Josh Smith’s CodeProject article about CommandGroup

这篇关于保存前WPF数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆