Search code examples
c#wpfxamldata-bindingrelativesource

Refactoring creation of a binding from code-behind based to XAML based


Today I'm using a constructor to receive an array and then bind it to the element.

C#

public MyDialog(Stuff stuff, IEnumerable<Thing> things)
{
  InitializeComponent();
  DataContext = stuff;
  MyComboBox.SetBinding(ComboBox.ItemsSourceProperty, new Binding { Source = things });
  ShowDialog();
}

XAML

<ComboBox x:Name="MyComboBox"
          DisplayMemberPath="Canonic"
          Style="{StaticResource DefaultComboBoxStyle}" />

I'd like to refactor it into purely XAML based approach and I've approached it in the following way. However, I get no values in my combo box now and I'm very unsure how to trouble-shoot it.

<ComboBox x:Name="MyComboBox"
          ItemsSource="{Binding 
            RelativeSource={
              RelativeSource FindAncestor,
              AncestorType={x:Type Window}},
            Path=DataContext.TheActualThings}"
          DisplayMemberPath="Canonic"
          Style="{StaticResource DefaultComboBoxStyle}" />-->

Of course, the class Things contains a number of fields, one of which is called Canonic and contains a string to render as the option description. The control creating the dialog is of type ProgramWindow deriving from Window.

Please note that there's a similar question (as it may appear) but the difference is that in the other, I had syntax issue and once that's resolved, there's the actual technical problem described here. (I'm not giving a link to the other question because I prefer not to affect the view count on it.)

public partial class ProgramWindow : Window
{
  public ProgramWindow()
  {
    InitializeComponent();
    DataContext = new ViewModel();
  }

  private void DataGridRow_OnDoubleClick(Object sender, MouseButtonEventArgs eventArgs)
  {
    MyDialog dialog = new MyDialog(
      (sender as DataGridRow).Item as Stuff,
      (DataContext as ViewModel).TheActualThings);

    if (dialog.DialogResult ?? false) ...
    else ...
  }
}

Solution

  • The problem is that you are trying to access the DataContext of another Window using a RelativeSource binding. The RelativeSource binding can only access elements within the same visual tree and the other Window cannot be accessed this way.