Связывание в ContentControl Crash - PullRequest
       17

Связывание в ContentControl Crash

11 голосов
/ 23 декабря 2010

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

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

<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; }

Ответы [ 3 ]

17 голосов
/ 23 декабря 2010

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

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; }
}
0 голосов
/ 05 декабря 2013

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

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

<ContentPresenter Content="{Binding}">
    <ContentPresenter.ContentTemplate>
        <DataTemplate>
            <Button Content="{Binding MyString}"/>
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>
0 голосов
/ 23 декабря 2010

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

...