Home > other >  How can I bind two user controls together?
How can I bind two user controls together?

Time:12-17

I'm stuck in a problem right now and I think I'm lost. My project (C# WPF MVVM) consists of the following components (no framework):

  • ShellView (Window)
  • ShellViewModel
  • MainView (Usercontrol) <-- 2 Textboxes for Userinputs (int values)
  • MainViewModel <-- Added both integer and put the result in a int-property
  • ResultDisplay (UserControl) <-- One Label witch should display the result

Both user controls are loaded into the shell view and displayed there.

How can I now connect the ResultDisply with the property of the MainView.

I've tried setting the Data.Context of the DisplayView to the MainViewModel and binding its label to the MainViewModel's property (ResultOutput). When setting the autoproperty (1234) it works and 1234 is displayed. But everything that changes during runtime is no longer displayed. I've already thought about DependensyProperty, but I can't implement it.

MainViewModel: `

private string resultOutput = "1234";

        public string ResultOutput
        {
            get { return resultOutput; }
            set 
            { 
                resultOutput = value; 
                OnPropertyChanged("Result");
            }
        }


        private void AddTwoNumbers()
        {
            int result = Num1   num2;
            ResultOutput = result.ToString();
        }

DisplayView:

<UserControl.DataContext>
        <viewModel:MainViewModel />
    </UserControl.DataContext>
    <Grid>
        <Label x:Name="ResultTB"
               Content="{Binding ResultOutput}"
                   Background="#333"
                   Foreground="LightGray"
                   FontSize="40"
                   HorizontalContentAlignment="Left"
                   VerticalContentAlignment="Bottom"
                   Padding="8,0,0,5" />

    </Grid>
</UserControl>

` I hope someone can help me out of the darkness. :-)

CodePudding user response:

<UserControl.DataContext>
        <viewModel:MainViewModel />
</UserControl.DataContext>

This is wrong approach, because you create new instance of MainViewModel.

I've had the same problem, solution (without DependencyProperty) that works for me is to place your UserControl inside container (for example StackPanel) and bind DataContext of this container.

class ShellViewModel
{
    public MainViewModel MainViewModel { get; }

    public ShellViewModel()
    {
        MainViewModel = new MainViewModel();
    }
}
<Window x:Class="ShellView" ...>
     <StackPanel DataContext="{Binding MainViewModel}">
         <MainView/>
         <ResultDisplay/>
     </StackPanel>
</Window>

So now MainView and ResultDisplay have the same ViewModel object

CodePudding user response:

Thanks for the quick reply. I tried to implement your solution but I guess I'm still doing something wrong. My ShellViewModel:

public class ShellViewModel : ObservableObject
{
    private MainViewModel mainVM;
    private object? currentView;

    public object? CurrentView
    {
        get { return currentView; }
        set 
        { 
            currentView = value; 
            OnPropertyChanged("CurrentView");
        }
    }

    public MainViewModel MainVM
    {
        get { return mainVM; }
        set 
        { 
            mainVM = value; 
            OnPropertyChanged("MainVM");
        }
    }

    public ShellViewModel()
    {
        MainVM = new MainViewModel();
        CurrentView = mainVM;
    }
}

My ShellView:

   xmlns:viewModel="clr-namespace:TestApp1.MVVM.ViewModels"
    mc:Ignorable="d"
    Title="ShellView" Height="650" Width="800">
<Window.DataContext>
    <viewModel:ShellViewModel />
</Window.DataContext>
<Grid DataContext="{Binding MainVM}">
    <Grid.RowDefinitions>
        <RowDefinition Height="150" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <local:ResultDisplay />
    
    <ContentControl x:Name="ActiveItem"
                    Content="{Binding}"
                    Grid.Row="1" />
</Grid>

My Display view, with the binding to the MainVM Property:

<Grid>
    <Label x:Name="ResultTB"
           Content="{Binding ResultOutput}"
               Background="#333"
               Foreground="LightGray"
               FontSize="40"
               HorizontalContentAlignment="Left"
               VerticalContentAlignment="Bottom"
               Padding="8,0,0,5" />

</Grid>

It's still showing the initial auto-property (1234) but if the property (ResultOutput) changed during runtime it doesn't show the new value.

  • Related