0
votes

When I enter text into a Textbox, it updates two TextBlocks at the same time. I'm trying to retrieve that value to save it to a sql database. I've temporarily set it up to display the value in a MessageBox.

ViewModel/Model:

private decimal _amount;

    public decimal Amount
    {
        get
        {
            return _amount;
        }
        set
        {
            _amount = value;
            OnPropertyChanged("Amount");
        }
    }

TextBox Binding:

<TextBox MaxLength="7" Visibility="{Binding Hide1, Converter={StaticResource BoolToVis},FallbackValue=Visible}" Text="{Binding Amount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" />

TextBlocks Binding:

<TextBlock Foreground="Black" Margin="0 0 0 0" VerticalAlignment="Top" Grid.Column="3" Text="{Binding Path=Amount}"/>
<TextBlock Grid.Column="3" Text="{Binding Amount}" Foreground="Black" Margin="0 0 0 0" VerticalAlignment="Bottom"/>

SaveCommand:

private async void Save()
    {
        try
        {
            MessageBox.Show(string.Format("{0}", Amount));
        }
        catch (DbEntityValidationException ex)
        {
            foreach (var en in ex.EntityValidationErrors)
            {
                var exceptionDialog = new MessageDialog
                {
                    Message = { Text = string.Format("{0}, {1}", en.Entry.Entity.GetType().Name, en.Entry.State) }
                };

                await DialogHost.Show(exceptionDialog, "RootDialog");

                foreach (var ve in en.ValidationErrors)
                {
                    exceptionDialog = new MessageDialog
                    {
                        Message = { Text = string.Format("{0}, {1}", ve.PropertyName, ve.ErrorMessage) }
                    };

                    await DialogHost.Show(exceptionDialog, "RootDialog");
                }
            }
        }
        catch(Exception ex)
        {
            var exceptionDialog = new MessageDialog
            {
                Message = { Text = string.Format("{0}", ex) }
            };

            await DialogHost.Show(exceptionDialog, "RootDialog");
        }

    }

When I hit save, the MessageBox displays 0.

EDIT: I've just remembered that I have the ViewModel connected to two UserControls. My TabLayout, which handles the content of TabItems; and Payroll which contains the save button and a TabControl which loads TabLayout into each TabItem.

DataContext for both is:

public TabLayout()
    {
        InitializeComponent();
        DataContext = new PayslipModel();
    }

public Payroll()
    {
        InitializeComponent();
        DataContext = new PayslipModel();
    }
1
Is all code here part of the same class? Are you sure it's all operating on the same instance of that class? Have you tried debugging this? - Pieter Witvoet
How/where do you set the datacontext to your ViewModel instance? - TaiT's
@TaiT's I set it in the code-behind like this DataContext = new PayslipModel(); - bruh1234
@PieterWitvoet Yes, all codes are in the same class and I do believe they're operating on the same instance of that class - bruh1234
The posted code should work. At least it works on my machine. Note that when binding to decimal you won't be able to enter a decimal point out of the box see Binding to decimal To further debug your binding add this PresentationTraceSources.TraceLevel=High to your TextBox If you see the value going into your property then your Save command is operating on a different instance. In that event post your code behind and how the save command is being called. - JSteward

1 Answers

1
votes

If you want both controls to share a DataContext then you can inject an instance from your composition root, i.e. App.Xaml.cs The following probably doesn't match the way your application is laid out but should give you the idea. Down the road you can look at dependency injection and how to compose your object graph but this a start.

App.xaml

<Application x:Class="App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                 
             Startup="OnAppStartup">
    <Application.Resources>

    </Application.Resources>
</Application>

App.xmal.cs

public partial class App : Application {

    private void OnAppStartup(object sender, StartupEventArgs e) {                        
        Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;
        var vm = new PayslipModel();
        var mainWindow = new MainWindow(vm);
        Application.Current.MainWindow = mainWindow;
        mainWindow.Show();
    }
}

MainWindow.xaml.cs

public MainWindow(PayslipModel vm){
    InitializeComponent();
    tabControl = new TabControl(vm);
    payRoll = new PayRoll(vm);
}

UserControls

public TabLayout(PayslipModel vm)
{
    InitializeComponent();
    DataContext = vm;
}

public Payroll(PayslipModel vm)
{
    InitializeComponent();
    DataContext = vm;
}