Using WindowsFormsHost inside WPF with two way binding MVVM - Get values from windows control on Save

60 Views Asked by At

I am new to WPF and am trying to use a Windows form control inside WPF in the MVVM pattern with two way binding using dependency objects. I found the following code online and made it work with dependency objects to achieve the required functionality. 

For now, I achieved the two-way binding by updating the attached property values (dependency object) on a button click within the Windows form control so that I could get the updated values in my view Model. I'm trying to see if there is any better way to get the updated values from the Windows Forms host control on the Save command from my viewmodel automatically. 

Windows form control:

    private Person _person;

    public WindowsFormControl()
    {
        InitializeComponent();
    }

    public void WorkYourMagic(Person person)
    {
        _person = person;
        TextBoxName.Text = person.Name;
        TextBoxAge.Text = Convert.ToString(person.Age);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (_person != null)
        {
            _person.Name = TextBoxName.Text;
            _person.Age = Convert.ToInt32(TextBoxAge.Text);
        }
    }
}

Finding ways to avoid the button1_click to update values and get from view model save command (or) get person object update with control values

wpf control

    public static readonly DependencyProperty ComplexPocoProperty = DependencyProperty.Register(
        "ComplexPoco",
        typeof(Person),
        typeof(WpfControl),
        new FrameworkPropertyMetadata(
            default(Person),
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            OnPropertyChanged));
    
    public WpfControl()
    {
        InitializeComponent();
    }

    public Person ComplexPoco
    {
        get { return (Person)GetValue(ComplexPocoProperty); }
        set { SetValue(ComplexPocoProperty, value); }
    }

    private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        WpfControl thisControl = (WpfControl)d;
        WindowsFormsHost wfHost = thisControl.MyHost;
        WindowsFormControl wf = (WindowsFormControl)wfHost.Child;
        wf.WorkYourMagic((Person)e.NewValue);
    }
}

View Model

    `private Person person;
    private readonly List<Person> repository;

    public ViewModel()
    {
        repository = new List<Person>
        {
            new Person { Name = "John", Age = 20 }, 
            new Person { Name = "Amber", Age = 24 },
            new Person { Name = "Sally", Age = 30 }, 
            new Person { Name = "Abe", Age = 50 }
        };

        ShowMagic = new DelegatingCommand(PickRandomPerson);
        SaveCommand = new DelegatingCommand(SaveFormValuesToDB);
    }


    private void SaveFormValuesToDB(object obj)
    {
        //How do I get windows form host control values/updated person object here
    }

    public Person Person
    {
        get { return person; }
        set
        {
            person = value;
            OnPropertyChanged("Person");
        }
    }

    public ICommand ShowMagic { get; set; }

    public ICommand SaveCommand { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private void PickRandomPerson()
    {
        int index = new Random().Next(0, repository.Count);
        Person = repository[index];
    }`

Main Window XAML

<StackPanel>
    <local:WpfControl ComplexPoco="{Binding Person,Mode=TwoWay}" />
    <Button Content="Show me the magic!" Command="{Binding ShowMagic}" />
</StackPanel>

WPF Control Xaml

<WindowsFormsHost 
    Name="MyHost">
    <local:WindowsFormControl/>
</WindowsFormsHost>
0

There are 0 best solutions below