Как вы можете динамически устанавливать DataContext в C #-коде?

#wpf #datacontext #dynamic

#wpf #datacontext #динамический

Вопрос:

Я создал RibbonGroupBox, подобный этому, в файле C #:

 public class TextControl : RibbonGroupBox
{
    public TextControl()
    {
        const double widthOfComboBoxes = 150;

        Binding fontsBinding = new Binding();
        fontsBinding.Source = (TextControlVM)DataContext;
        fontsBinding.Path = new System.Windows.PropertyPath("Fonts");
        fontsBinding.Mode = BindingMode.TwoWay;

        Binding fontSizeBinding = new Binding();
        fontSizeBinding.Source = (TextControlVM)DataContext;
        fontSizeBinding.Path = new System.Windows.PropertyPath("FontSize");
        fontSizeBinding.Mode = BindingMode.TwoWay;

        /* Combobox for the fonts (Arial, etc.) */
        Fluent.ComboBox fontCombo = new Fluent.ComboBox();
        fontCombo.SetBinding(Fluent.ComboBox.ItemsSourceProperty, fontsBinding);
        fontCombo.SelectedItem = ((TextControlVM)DataContext).DefaultFont;
        fontCombo.Width = widthOfComboBoxes;
        this.AddChild(fontCombo);

        /* Combobox for the fontsizes */
        Fluent.ComboBox fontSizeCombo = new Fluent.ComboBox();
        fontSizeCombo.SetBinding(Fluent.ComboBox.ItemsSourceProperty, fontSizeBinding);
        fontSizeCombo.SelectedItem = ((TextControlVM)DataContext).DefaultFontSize;
        fontSizeCombo.Width = widthOfComboBoxes;
        this.AddChild(fontSizeCombo);
    }
}
  

Кроме того, у меня есть viewmodel (TextControlVM), который содержит свойства для шрифтов, FontSize, DefaultFont и DefaultFontSize по умолчанию.

Когда я теперь использую это в другом подобном модуле, DataContext в приведенном выше примере равен null:

 <Fluent:RibbonTabItem Header="Export">
    <TextControl DataContext="{Binding DataContext.TextControl}"/>
</Fluent:RibbonTabItem>
  

Когда я создаю RibbonGroupBox с помощью кода XAML, все работает нормально, поэтому я хочу делать то, что автоматически делает XAML. Как я могу это сделать?

Справочная информация: Я хочу использовать RibbonGroupBox в нескольких модулях. Вот почему я создаю его с помощью C #-Code, чтобы я мог получить к нему доступ динамически. DataContext будет меняться в зависимости от вызова.

Ответ №1:

DataContext Автоматически подразумевается в привязке, поэтому вы, по сути, привязываетесь к RibbonTabItem.DataContext.DataContext.TextControl , которого не существует

Для привязки к RibbonTabItem.DataContext.TextControl просто оставьте лишнее DataContext вне привязки

 <Fluent:RibbonTabItem Header="Export">
    <TextControl DataContext="{Binding TextControl}"/>
</Fluent:RibbonTabItem>
  

Комментарии:

1. К сожалению, это не сработало. По-прежнему DataContext равен null.

2. @Hauke Я бы посоветовал использовать такой инструмент, как Snoop, и убедиться, что ваш RibbonTabItem содержит DataContext свойство с именем TextControl , которое имеет тип TextControlVM . Веб-сайт Snoop является snoopwpf.codeplex.com

3. Просто еще один вопрос: если я просто напишу <TextControl DataContext=»{Привязка DataContext}»/>, не должен ли DataContext быть not null тогда?

4. @Hauke, который попытался бы выполнить привязку к RibbonTabItem.DataContext.DataContext . Привязки обычно не генерируют исключение при возникновении ошибки, такой как значение, равное null, поэтому иногда их трудно отлаживать. Иногда вы можете просматривать ошибки привязки в окне отладки, хотя обычно я просто использую Snoop для отладки своих привязок. И если вы хотите выполнить привязку к RibbonTabItem.DataContext , используйте {Binding } (путь не указан)