简体   繁体   中英

How do I bind a XAML TextBox to either another TextBox's input or its own input, and then save the input to the data object in MVVM?

I have 2 pairs of textboxes for user input (see XAML below). In the vast majority of cases, the input for A1 and A2 is going to be identical to B1 and B2, so I added the bindings for txtDataB1 and txtDataB2 to "mirror" the input to A1 and A2, which does work in the UI. Data typed into A1/A2 saves fine since its bound to the dataStore , but I have some problems:

How do I save the values entered in txtDataB1 and txtDataB2 (either from manual user entry or mirrored data from A1/A2) to the dataStore object? I'm not familiar enough with XAML/MVVM/etc to know if there's a "pure-XAML" way of doing this with MultiBindings or something, or if there was some logic I'd have to make/call in the View Model.

<!-- Data A -->
<TextBox Name="txtDataA1" Text="{Binding dataStore.A1}" />
<TextBox Name="txtDataA2" Text="{Binding dataStore.A2}" />

<!-- Data B -->
<TextBox Name="txtDataB1" Text="{Binding ElementName=txtDataA1, Path=Text, Mode=OneWay}" />
<TextBox Name="txtDataB2" Text="{Binding ElementName=txtDataA2, Path=Text, Mode=OneWay}" />

Forget about trying to application implement logic like this in "pure XAML" and implement it in a view model instead. XAML is a markup language.

The setter of A1 should set B1 and the setter of A2 should set B2 , eg:

public class ViewModel : INotifyPropertyChanged
{
    private string _a1;
    public string A1
    {
        get { return _a1; }
        set { _a1 = value; NotifyPropertyChanged(); B1 = value; }
    }

    private string _b1;
    public string B1
    {
        get { return _b1; }
        set { _b1 = value; NotifyPropertyChanged(); }
    }

    //+the same for A2 and B2

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

Saving the data is then simply a matter of getting the values from the B1 and B2 properties, not matter how they were set.

This can be solved by using TwoWay binding, but TextBox is updated by LostFocus in default, change its UpdateSourceTrigger is also needed, the code will be as following:

<!-- Data A -->
<TextBox Name="txtDataA1" Text="{Binding dataStore.A1, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Name="txtDataA2" Text="{Binding dataStore.A2, UpdateSourceTrigger=PropertyChanged}"/>

<!-- Data B -->
<TextBox Name="txtDataB1" Text="{Binding ElementName=txtDataA1, Path=Text, Mode=TwoWay}" />
<TextBox Name="txtDataB2" Text="{Binding ElementName=txtDataA2, Path=Text, Mode=TwoWay}" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM