Привязка в ContentControl Crash

Может ли кто-нибудь сказать мне, почему это приводит к сбою моего приложения? Кажется, есть какая-то бесконечная рекурсия, я не могу понять, почему. Я получаю это исключение

При обходе дерева превышена логическая глубина дерева. Это может указывать на цикл в дереве

<ContentControl Content="{Binding}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Button Content="{Binding MyString}"/>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

И это все, что у меня есть в качестве источника

    public MainWindow()
    {
        InitializeComponent();
        MyString = "Test";
        this.DataContext = this;
    }

    public string MyString { get; set; }

person ImJames    schedule 23.12.2010    source источник


Ответы (3)


Вы используете MainWindow в качестве DataContext содержимого MainWindow. Когда вы устанавливаете Content="{Binding}" в ContentControl, это устанавливает содержимое ContentControl в экземпляр MainWindow. Это проблема, потому что ContentControl содержится в содержимом MainWindow. Всякий раз, когда свойство Content получает UIElement, оно отображает его как UIElement, а не через DataTemplate, как это было бы с классом без пользовательского интерфейса. Таким образом, ваше дерево становится

MainWindow
 ContentControl
  MainWindow
   ContentControl
    ...

Использование отдельного объекта данных для вашего DataContext вместо самого окна даст вам поведение, которое вы ищете:

public partial class Window13 : Window
{
    public Window13()
    {
        InitializeComponent();
        MyData data = new MyData();
        data.MyString = "Test";
        this.DataContext = data;
    }
}

public class MyData
{
    public string MyString { get; set; }
}
person John Bowen    schedule 23.12.2010
comment
Джон, ты мужчина!! Работает как шарм :) Наконец-то я могу забыть об этой проблеме, и я также знаю причину благодаря вашему очень ясному объяснению! Спасибо и счастливого Рождества - person ImJames; 24.12.2010

Хотя я полностью согласен с принятым ответом, что вам не следует этого делать, иногда у вас просто нет выбора. Например, я использую Xceed PropertyGrid и DataContext для каждого элемента сетка представляет собой PropertyItem, который является UIElement (содержащим фактические данные в элементе Value).

Обходной путь, который я нашел, заключается в использовании ContentPresenter вместо ContentControl. В документации нет ясности по этому поводу, но кажется, что UIElement создаются по шаблону, а не используются как есть.

<ContentPresenter Content="{Binding}">
    <ContentPresenter.ContentTemplate>
        <DataTemplate>
            <Button Content="{Binding MyString}"/>
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>
person Benlitz    schedule 05.12.2013

Вы должны удалить привязку к свойству Content элемента управления ContentControl. Что это вообще должно делать?

person gstercken    schedule 23.12.2010
comment
Насколько я понимаю ContentControl, DataContext в DataTemplate является содержимым ContentControl, а не DataContext. Поэтому, если я удалю его, я вообще не получу DataContext в DataTemplate для привязки. Есть идеи? - person ImJames; 23.12.2010