2011-05-24 10 views
4

私はWPFでtreeviewを使用しており、バインドされたコレクションをリロードするときに状態(展開とフォーカス)を失いたくありません。私は項目を選択するために、DependencyPropretyを使用WPFツリービュー最初のノードと選択した項目のみを展開しますか?

private void ExpandFirstNodeTree() 
    { 
     foreach (var item in TreeviewModel.Items) 
     { 
      TreeViewItem itm = (TreeViewItem)TreeviewModel.ItemContainerGenerator.ContainerFromItem(item); 
      if (itm == null) continue; 
      itm.IsExpanded = true; 
     } 
    } 

は、最初のロードでは、それだけで最初のノードを展開するのは簡単です、私は次のコードを使用します。 TreeViewを探索し、TreeViewItemを見つけてアイテム "IsSelected"プロパティをtrueに設定します。

private static readonly DependencyProperty SelectedEntityCodeProperty = 
     DependencyProperty.Register(PropertyHelper.GetName((EntitiesTreeview e) => e.SelectedEntityCode), typeof (string), typeof (EntitiesTreeview)); 

    public string SelectedEntityCode 
    { 
     get { return (string) GetValue(SelectedEntityCodeProperty); } 
     set { SetValue(SelectedEntityCodeProperty, value); } 
    } 

    public EntitiesTreeview() 
    { 
     InitializeComponent(); 
     Loaded += new RoutedEventHandler(EntitiesTreeview_Loaded); 
    } 

    private void LoadSelectedItem() 
    { 
     if ((!string.IsNullOrEmpty(SelectedEntityCode)) 
      && (TreeviewEntity.SelectedItem == null)) 
      ChangeSelectedItem<ENTITY>(SelectedEntityCode, TreeviewEntity); 
    } 

    private bool ChangeSelectedItem<T>(string entityCode, ItemsControl itemsControl) where T : ENTITYBASE 
    { 
     if (itemsControl != null) 
     { 
      foreach (var item in itemsControl.Items) 
      { 
       var currentContainer = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem; 
       if ((currentContainer != null) 
        && (item is T) 
        && ((item as T).CCODE == entityCode)) 
       { 
        currentContainer.IsSelected = true; 
        var selectMethod = typeof (TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance); 
        selectMethod.Invoke(currentContainer, new object[] {true}); 
        return true; 
       } 
       if (ChangeSelectedItem<T>(entityCode, currentContainer)) 
        return true; 
      } 
     } 
     return false; 
    } 

私の問題は、私はアイテムのコレクションをリロードするとき、フォーカスが失われた(選択項目)と拡張項目が折りたたまれ、あります。バインドされたアイテムとUIをどのように分けることができますか? 最後に、選択した項目をプログラムで設定したいと思います。依存関係プロパティが変更されたときに、選択したアイテムを再ロードするにはどうすればよいですか?

私はすでにジョシュスミスのソリューション(http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx)を見てきましたが、私のバインディングにViewModelコレクションを使用したくありません。私はIMO ... painfullすることで結合して、ビューモデルを使用する別のオブジェクト型を持っている:)

感謝IMO

+0

「アイテムコレクションをリロードする」という意味が実際にはわかりません。 – Cilvic

答えて

7

Iが結合してpainfullすることになりますのViewModelを使用する別のオブジェクト型を持っているの...ビューモデルを使用してないがあまりにも苦痛である理由

は実際には、あなたが今経験している問題は、正確に示しています。

ビューモデルを作成する場合は、ビューモデルクラスにIsSelectedIsExpandedプロパティを実装できます。その後、TreeViewItemの関連プロパティをバインドすることができます。これを行うと、UIの状態の変更がビューモデルのデータに反映され、データからUIをリロードすると、状態の変更は保持されます。

これは達成しようとしていることを達成するための最も簡単な方法です。追加のメリットとして、上に投稿した謎めいたテスト困難なコードビハインドの最後のすべてを廃棄することができます。

関連する問題