0

I'm relatively new to WPF, and MVVM is over my head right now, so I'm looking for a solution to bind Combo Box ItemsSource of a user control to a parent window's member. I've looked up many examples and related answers on stackoverflow and elsewhere, but they refer to MVVM design, and I'm trying to get the basics of WPF right now.

Following is what I've tried to do based on the second suggestion from Add items to ComboBox at runtime? and advice from How do I use WPF bindings with RelativeSource?. You'll notice UserControl1.xaml uses RelativeSource to bind the combo box's ItemsSource.

MainWindow.xaml

<Window x:Class="DataBindingTest1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataBindingTest1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:UserControl1/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;

namespace DataBindingTest1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public List<string> memberData;

        public MainWindow()
        {
            memberData = new List<string>();
            memberData.Add("Item 1");
            memberData.Add("Item 2");
            memberData.Add("Item 3");

            InitializeComponent();
        }
    }
}

UserControl1.xaml

<UserControl x:Class="DataBindingTest1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:DataBindingTest1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120"
                  ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=memberData}"/>

    </Grid>
</UserControl>

UserControl1.xaml.cs

using System.Windows.Controls;

namespace DataBindingTest1
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
Jay Tennant
  • 181
  • 10
  • Just make memberData as property. – sTrenat Sep 27 '17 at 20:21
  • You can access The Mainwindow via static `Application.Current.MainWindow`. then you could just set the binding in your code behind. But i would recommend learning MVVM as it will save plenty of headache. If you are just writing this to learn, then cool, but you shouldnt be doing something like this in production. – Ginger Ninja Sep 27 '17 at 20:25
  • Don't do that at all, because it makes you control depend on the MainWindow class. Instead, add an ItemsSource dependency property to the UserControl and bind it "internally" with `RelativeSource={RelativeSource AncestorType=UserControl}`. Or better, don't use a UserControl and derive a control directly from ComboBox. Is there actually anything else in the UserControl except the ComboBox? – Clemens Sep 27 '17 at 20:25
  • @sTrenat I think I did in MainWindow.xaml.cs. Or are you referring to something else? – Jay Tennant Sep 27 '17 at 20:32
  • @GingerNinja I'd like to avoid referring to a static instance if possible, and set the binding in the xaml, not code behind. But maybe that's not possible? I will take time on MVVM when I can. – Jay Tennant Sep 27 '17 at 20:33
  • @Clemens I don't understand, sorry. Bind the user control to itself? Or have it look for another user control? Or have the main window bind to the user control? Also, I must use a user control, the combo box is only one element of all elements needed in it. – Jay Tennant Sep 27 '17 at 20:37
  • @sTrenat I get it now, making memberData as a property made it visible to the control, simple and effective! – Jay Tennant Sep 27 '17 at 21:19
  • @Clemens I understand the linked answer as how to properly encapsulate control data. I demonstrated both this and sTrenat's solution as working, and will edit the OP with the answer (since I cannot answer). – Jay Tennant Sep 27 '17 at 21:20
  • Having a MemberData property in the MainWindow class and binding to it in a UserControl is bad design. As said, it makes your UserControl dependent on the MainWindow class, and hence not reusable. Better follow the approach from the duplicate question's answer. – Clemens Sep 27 '17 at 22:03
  • Note also that there is no need in editing an answer into a question when it is marked as a duplicate. It's irrelevant for future readers how you finally implemented a solution. – Clemens Sep 27 '17 at 22:08
  • @Clemens I wasn't looking for reusable. It isn't bad design unless reuse and independence is the goal. I edited the answer because sTrenat provided the simplest example to prove a point. That is how _I_ learn, and others may learn that way, too. – Jay Tennant Sep 28 '17 at 03:42

0 Answers0