2009-07-20 3 views
10

Я изменил свой вопрос, так как он изменил фокус при попытке разобраться. Я сузил проблему до следующего ...WPF - Databind to StackPanel с использованием DataTemplates

Я пытаюсь привязать выбранный элемент TreeView к StackPanel (или к другому контейнеру, который может содержать элементы управления пользователя). Затем этот контейнер отобразит UserControl, в зависимости от типа выбранного элемента.

Вот XAML из StackPanel (как TreeView и StackPanel находятся в том же окне ==> другой столбец сетки)

<StackPanel Grid.Column="2" MinWidth="500" DataContext="{Binding ElementName=myTree, Path=SelectedItem, Mode=OneWay}"> 
    <StackPanel.Resources> 
     <DataTemplate DataType="{x:Type mvTypes:MyTypeA}"> 
      <controls:UserControlA DataContext="{Binding}" /> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type mvTypes:MyTypeB}"> 
      <controls:UserControlB DataContext="{Binding}" /> 
     </DataTemplate> 
    </StackPanel.Resources> 
</StackPanel> 

Когда я помещаю пользовательский элемент управления непосредственно под StackPanel (не в ресурсах), он отображает его с выбранным объектом в качестве своего datacontext. Если я помещаю в него текстовое поле, он отображает правильный тип выбранного элемента.

<TextBox Name="textBox1" Text="{Binding}" /> 

По какой-то причине, поместив его в DataTemplate (даже без установки DATATYPE) результатов ни в чем, чтобы отобразить.

Любые санкции. Я думаю, что, возможно, StackPanel не подходит для этого, хотя я не могу найти другие элементы управления, которые выглядят подходящими как контейнеры, подобные этому.

Заранее благодарен.

ответ

11

Замените StackPanel в вашем примере на ContentPresenter, а вместо DataContext установите свойство Content. Это должно сработать.

+0

Точно! DataContext ничего не значит, это просто для привязки. Свойство контента - вот что для представления вещей. –

+0

Большое вам спасибо. Он отлично работает. Любой вклад в почему он не работал с помощью StackPanel? – Ronald

+1

Как сказал Олег, DataContext ничего не значит сам по себе, именно там будут работать какие-либо привязки ниже этого. Подумайте об этом, например, о том, как установить фрейм стека или область видимости переменной. Вам нужно было создать привязку и оценить ее и отобразить, что означает ContentPresenter (для отдельного элемента) или ItemsPresenter (для коллекции). сделано для. Попробуйте найти ContentPresenters и DataTemplates и посмотреть, как они на самом деле взаимодействуют. Я не знаю никаких хороших сообщений в блоге, но, вероятно, есть некоторые из них. –

0

Хотя вы установили привязку ко второму настраиваемому элементу управления, вы устанавливаете DataContext, поскольку привязка является маршрутом к информации, а DataContext - информацией, к которой она применяет эту привязывающую информацию.

Andrew

+0

Да, datacontext установлен в пользовательском контроле, таком как это ... (очень упрощено, конечно) ModelObject c = repo.GetByID (3295123); ViewModelTree vmt = new ViewModelTree (c); base.DataContext = vmt; Может ли быть, что я привязываюсь только к DataContext пользовательского элемента управления, а не к окну и, следовательно, не отображается другим элементам управления в окне? – Ronald

0

Вы можете создать UserControl для отображения TreeView и информации выбора на праве, все в одном. Это избавляет вас от создания какого-либо настраиваемого элемента управления. Пользовательский элемент управления в основном не нужен, поскольку вы не создаете ничего, чего раньше не было.

<UserControl x:Class="NameSpace.SelectionView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:controls="namespace.Controls" 
    Height="300" Width="300"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <TreeView Name="customTree"> 
      <!--Items go here--> 
     </TreeView> 
     <StackPanel Grid.Column="1" MinWidth="50" DataContext="{Binding ElementName=customTree, Path=SelectedItem, Mode=OneWay}"> 
      <StackPanel.Resources> 
       <DataTemplate DataType="{x:Type StylingTest:CustomViewModelA}"> 
        <controls:CustomADetailsControl /> 
       </DataTemplate> 
       <DataTemplate DataType="{x:Type StylingTest:CustomViewModelB}"> 
        <controls:CustomBDetailsControl /> 
       </DataTemplate> 
      </StackPanel.Resources> 
      <TextBlock Text="{Binding}"/> 
     </StackPanel> 
    </Grid> 
</UserControl> 

Любое другое индивидуальное поведение, я уверен, что вы можете создавать или устанавливать в стилях/шаблонах здесь.

Кроме того, вы можете найти один из моих других answer s полезный.

Удачи вам в wpf, ура.

+0

Спасибо. Это то, что я пытался выполнить сейчас, только прямо в окне xaml (а не в usercontrol). Хотя выбор элементов управления деталью (пользователя) в панели стека не работает, TextBlock действительно отображает тип выбранного элемента treeview. – Ronald

Смежные вопросы