GTD
GTD

Reputation: 325

Binding UpdateSourceTrigger=Explicit, updates source at program startup

I have following code:

<Window x:Class="WpfApplication1.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">
<Grid>
    <TextBox Text="{Binding Path=Name, 
                            Mode=OneWayToSource, 
                            UpdateSourceTrigger=Explicit, 
                            FallbackValue=default text}" 
             KeyUp="TextBox_KeyUp" 
             x:Name="textBox1"/>
</Grid>

    public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void TextBox_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            BindingExpression exp = this.textBox1.GetBindingExpression(TextBox.TextProperty);
            exp.UpdateSource();
        }
    }
}



    public class ViewModel
{
    public string Name
    {
        set
        {
            Debug.WriteLine("setting name: " + value);
        }
    }
}



    public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        Window1 window = new Window1();
        window.DataContext = new ViewModel();
        window.Show();
    }
}

I want to update source only when "Enter" key is pressed in textbox. This works fine. However binding updates source at program startup. How can I avoid this? Am I missing something?

Upvotes: 6

Views: 16684

Answers (2)

Tim Pohlmann
Tim Pohlmann

Reputation: 4440

The problem is, that DataBinding is resolved on the call of Show (and on InitializeComponent, but that is not important for you, because at that point your DataContext is not set yet). I don't think you can prevent that, but I have an idea for a workaround:

Do not set the DataContext before you call Show(). You can achieve this (for example) like this:

public partial class Window1 : Window
{
    public Window1(object dataContext)
    {
        InitializeComponent();

        this.Loaded += (sender, e) =>
        {
            DataContext = dataContext;
        };
    }
}

and:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    Window1 window = new Window1(new ViewModel());
    window.Show();
}

Upvotes: 0

Nitin Chaudhari
Nitin Chaudhari

Reputation: 1507

Change your Binding Mode to Default

<TextBox Text="{Binding Path=Name, 
                    Mode=Default, 
                    UpdateSourceTrigger=Explicit, 
                    FallbackValue=default text}" 
        KeyUp="TextBox_KeyUp" 
        x:Name="textBox1"/>

Upvotes: -2

Related Questions