2014-02-20 2 views
0

Я пытаюсь привязать коллекцию к древовидной структуре. Моя попытка до сих пор не удалась. Я пропустил что-то, несмотря на статьи, которые я прочитал по этому поводу.Связывание коллекции с Treeview в WPF

До сих пор я пробовал что-то вроде, но Treeview просто зарисовывает идентификатор класса A и, тем самым, без кнопки для расширения.

<Grid> 
     <TreeView HorizontalAlignment="Left" Height="270" VerticalAlignment="Top" Width="292" ItemsSource="{Binding ManagerObjects}"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="{x:Type local:ManagerObject}" ItemsSource="{Binding MyManager}"> 
        <TextBlock Text="{Binding Id}"/> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type local:Manager}" ItemsSource="{Binding ManagerClientServerProperty}"> 

        <TextBlock Text="{Binding ManagerClientServerProperty}"/> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type local1:ManagerClientServer}"> 

        <TextBlock Text="TEST"/> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type local1:NetworkObject}" ItemsSource="{Binding Entities}"> 

        <TextBlock Text="TEST"/> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type local1:RemoteEntity}" ItemsSource="{Binding Fields}"> 
        <TextBlock Text="TEST"/> 
        <!-- how classD should look like --> 
       </HierarchicalDataTemplate> 
      </TreeView.Resources> 

     </TreeView> 

    </Grid> 

EDIT: ДОБАВЛЕНИЕ РЕАЛЬНОГО КОД

Это в моей модели:

public class ManagerObject 
{ 
    // PROPERTIES 
    public int Id { get; private set; } 
    public Manager MyManager { get; private set; } 
} 

public class Manager 
    { 
    // FIELDS 
     private readonly ManagerClientServer managerClientServer; 
    // PROPERTIES 
     public ManagerClientServer ManagerClientServerProperty { get { return managerClientServer;} } 

    /**** OTHER STUFF NON IMPORTANT ****/ 

    } 

public class ManagerClientServer 
{ 
    // FIELDS 
    private readonly ObservableCollection<NetworkObject> Clients = new ObservableCollection<NetworkObject>(); 
    private readonly ObservableCollection<NetworkObject> Servers = new ObservableCollection<NetworkObject>(); 
    // PROPERTIES 
    public ObservableCollection<NetworkObject> ClientsProperty 
    { 
     get { return Clients; } 
    } 

    public ObservableCollection<NetworkObject> ServersProperty 
    { 
     get { return Servers; } 
    } 
    /*** OTHER STUFF NON IMPORTANT HERE ***/ 
} 
public class NetworkObject 
{ 
    // FIELDS 
    private readonly ObservableCollection<RemoteEntity> _entities=new ObservableCollection<RemoteEntity>(); 
    public uint NetworkId { get; private set; } 
    // PROPERTIES 
    public ObservableCollection<RemoteEntity> Entities 
    { 
     get { return _entities; } 
    } 
    // CONSTRUCTOR 
    public NetworkObject(uint id) 
    { 
     NetworkId = id; 
    } 
} 

    public class RemoteEntity 
{ 
    // FIELDS 
    private readonly ObservableCollection<int> _fields=new ObservableCollection<int>(); 
    // PROPERTIES 

    public bool IsLost { get; set; } 
    public bool NeedUpdate { get; set; } 
    public uint SessionId { get; private set; } 
    public ObservableCollection<int> Fields 
    { 
     get { return _fields; } 
    } 
    // CONSTRUCTOR 
    public RemoteEntity(uint id) 
    { 
     SessionId = id; 
    } 
} 

ViewModel просто разоблачить это свойство:

public ObservableCollection<ManagerObject> ManagerObjects 
     { 
      get { return managerObjects; } 

      set 
      { 
       managerObjects = value; 
       NotifyOfPropertyChange(()=>ManagerObjects); 
      } 
     } 
private ObservableCollection<ManagerObject> managerObjects; 

Инициализация только 2 ManagerObject, после этого все они включают случайное число r NetworkObjects как в коллекции клиентов, так и в серверах, и каждый из них имеет случайное число Entities.

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

Большое спасибо.

+1

Не должен ли ваш ItemsSource быть набором классов? Это будет класс parent-child, а по классу - ваш фактический класс сущности. Я предполагаю, что ваша коллекцияClassA имеет только элемент 1 с классом в нем. Можете ли вы показать больше кода, например, вашей модели и viewmodel –

+0

collectionclassA является ObservableCollection с двумя элементами в нем. Свойство моего ViewModel. – user3091460

+0

Вы хотите создать ObservableCollection , который включает ClassA, ClassD, ClassE с дочерним свойством, которое также является наблюдаемым , которое содержит их соответствующий дочерний элемент. –

ответ

1

А, я вижу вашу проблему сейчас, и это очень простой. Вы ничего не можете расширять, потому что нечего расширять. Ваш TreeView.ItemsSource связан с коллекцией ManagerObjects, и это нормально, потому что это коллекция. Тем не менее, в вашем HierarchicalDataTemplate для вашего типа данных ManagerObject, у вас есть это:

<HierarchicalDataTemplate DataType="{x:Type local:ManagerObject}" 
    ItemsSource="{Binding MyManager}"> <!-- Look here --> 
    <TextBlock Text="{Binding Id}"/> 
</HierarchicalDataTemplate> 

Вы пытаетесь связать данные MyManager свойство к HierarchicalDataTemplate.ItemsSource собственности, но вы не можете, потому что это не коллекция. Вместо этого, попробуйте следующее:

<DataTemplate DataType="{x:Type local:ManagerObject}"> 
    <StackPanel> 
     <TextBlock Text="{Binding Id}" /> 
     <ContentControl Content="{Binding MyManager}" /> 
    </StackPanel> 
</DataTemplate> 

Вы будете иметь другие проблемы, как это тоже, так что вам придется настроить несколько ваших шаблонов. Например, это не будет работать, потому что ManagerClientServerProperty свойство не коллекция:

<HierarchicalDataTemplate DataType="{x:Type local:Manager}" 
    ItemsSource="{Binding ManagerClientServerProperty}"> 
    ... 
</HierarchicalDataTemplate> 

Вы могли это сделать:

<HierarchicalDataTemplate DataType="{x:Type local:Manager}" 
    ItemsSource="{Binding ManagerClientServerProperty.Clients}"> 
    ... 
</HierarchicalDataTemplate> 

... но тогда это будет только один коллекций. При написании WPF я узнал, что всегда лучше всего сделать ваши данные правильной формой в соответствии с вашим пользовательским интерфейсом. Обычно это означает добавление нескольких дополнительных свойств здесь и там, чтобы упростить вашу работу. Например, вместо использования CompositeCollection в пользовательском интерфейсе вы можете просто добавить дополнительное свойство в свой класс ManagerClientServer.Может быть, что-то вроде этого:

public ObservableCollection<NetworkObject> NetworkObjects 
{ 
    get 
    { 
     hhh networkObjects = new ObservableCollection<NetworkObject>(Clients); 
     networkObjects.Add(Servers); 
     return networkObjects; 
    } 
} 

Тогда вы могли бы сделать это:

<HierarchicalDataTemplate DataType="{x:Type local:Manager}" 
    ItemsSource="{Binding ManagerClientServerProperty.NetworkObjects}"> 
    ... 
</HierarchicalDataTemplate> 

Во всяком случае, я думаю, вы получите картину, так что я надеюсь, что вы можете закончить отдых самостоятельно. О, еще одна вещь ... не удивляйтесь, если это не сработает, потому что ваши данные не в правильной форме, которую ожидает TreeView. Это может работать, но если нет, забудьте HierarchicalDataTemplate и просто определите ListBox es в DataTemplate s для привязки к внутренним коллекциям.

+0

Итак, мы ближе, с вашим решением я могу видеть элементы класса B, но не в способе развернуть/свернуть, его, как ContentControl, просто сопоставляет другую стекную панель в стеке. Итак, что я вижу, это класс B чуть ниже класса A, но я не могу заставить его появляться/исчезать – user3091460

+0

См. Редактирование в моем последнем абзаце. – Sheridan

+0

Хорошо спасибо, его оценили. Я понимаю концепцию списка для коллекции, но почему я не могу развалиться/расшириться для первых отношений? – user3091460

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