.NETコンポーネント-検索付きのツリービュー

TreeViewの検索が必要になったときに、検索の実装を制御不能にしてから、 SelectedItemプロパティを設定しました。

残念ながら、標準のWPF TreeViewコントロールには、読み取り専用のSelectedItemプロパティがあります。

したがって、 TreeViewに表示されるIsSelectedプロパティとIsExpandedプロパティを各オブジェクトに導入し、これらのプロパティを対応するTreeViewItemプロパティに関連付ける必要がありました。 ( 通常、これは彼らがインターネットでアドバイスすることです

したがって、必要なオブジェクトにIsSelectedをインストールし、そのすべての祖先にIsExpandedをインストールするだけです。

この実装は正常に機能しますが、...

  1. ビジネスオブジェクトIsSelectedおよびIsExpandedを持つのはあまり良くありません。 また、ツリー内の各アイテムのビューモデルを作成するのは面倒です。
  2. ツリー検索は、コードに毎回実装する必要があります。これには、少なくとも時間がかかり、1つの単語で混乱が生じます。




一般的に、少し考えた後、そのような概念に来ました。





これは、すべてのテンプレートを検索する方法です。 ここではすべてが比較的簡単です。

public override void OnApplyTemplate() { base.OnApplyTemplate(); templateDescrColl = new TemplateDescriptionCollection();//    List<FrameworkElement> parents= Helper.GetAllParent(this);//    FindDataTemplatesResources(this.Resources);//      foreach (FrameworkElement parent in parents) //     { FindDataTemplatesResources(parent.Resources); } FindDataTemplatesResources(System.Windows.Application.Current.Resources);//      }
      
      





テンプレートを検索するためのロジックは次のとおりです。検索パスを指定する別の方法があることを除いて、すべてが計画どおりです。

これは、バインダーの検索が常に機能するとは限らないため、一方で必要になる場合があります。

(別のコントロールを使用してノードを表示する場合、その複雑なロジックでは確実に機能しません)。

さて、一方で、検索のパスをより正確に示す必要がある場合があります。

パスは、文字列「TypeName1:Property1、Property2 TypeName2:」としてFindPatchesプロパティを介して設定されます。

この場合、TypeName1はProperties1、Property2によって検索され、TypeName2はまったく検索されません。

  private void FindDataTemplatesResources(ResourceDictionary Resource) { foreach (object xxx in Resource.Values) { DataTemplate dataTemplate = xxx as DataTemplate; if (dataTemplate != null)//  a DataTemplate { bool hierarhical=false; if (!templateDescrColl.ExistType(dataTemplate.DataType as Type, out hierarhical))//     { TemplateBindingDescr templateBindingDescr = new TemplateBindingDescr();// HierarchicalDataTemplate hdt = xxx as HierarchicalDataTemplate;//  HierarchicalDataTemplate here if (hdt != null) { Binding ItemsSourceBinding = hdt.ItemsSource as Binding; string ItemsSourcePath = ItemsSourceBinding.Path.Path; templateBindingDescr.itemSourcePath = ItemsSourcePath;//       templateBindingDescr.IsHierathical = true; } Type tType = dataTemplate.DataType as Type; templateBindingDescr.TargetType = tType; // type  if (! String.IsNullOrWhiteSpace (FindPatches) && FindPatches.Contains (tType.Name + ":")) //       { Match match = Regex.Match (FindPatches, tType.Name + ":([^:]*)");. if (match.Success) { string re = match.Groups [1]. Value; string [] pathes = re.Split (','); templateBindingDescr.BindingPathes.AddRange (pathes); } } else //       { FrameworkElement frameworkElement = dataTemplate.LoadContent () as FrameworkElement; //   List <FrameworkElement> DependencyObjects = Helper.GetAllVisualChildren (frameworkElement);//     if (DependencyObjects!= null) { foreach (FrameworkElement dependencyObject in DependencyObjects) { //    BindingExpression BE = System.Windows.Data.BindingOperations.GetBindingExpression (dependencyObject, TextBlock.TextProperty); if (BE!= null) { string path = BE.ParentBinding.Path.Path; templateBindingDescr.BindingPathes.Add (path); } } } } templateDescrColl.Add (templateBindingDescr); //    } } } }
      
      





これは、検索テキストを含むすべての要素の検索方法です。

  /// <summary> ///                     FindText ///    /// </summary> /// <param name="control"></param> /// <param name="FindText"></param> /// <returns></returns> public List<NamedObject> FindObjectByPropertyNames(IEnumerable itemsSource, List<int> path) { List<NamedObject> ret = new List<NamedObject>();//       int i = 0; path.Add(i);//      foreach (object Item in itemsSource) //    { path[path.Count - 1] = i;//      TemplateBindingDescr desctiption= templateDescrColl.Get(Item.GetType());//        string subItemsPath=desctiption.itemSourcePath;//      string ObjectText=String.Empty;//           bool ok=false; foreach (string findPath in desctiption.BindingPathes)//         { object ItemVal = Item.GetObjectSubItem(findPath); //    if (ItemVal != null )//    { string ItemText = ItemVal.ToString().ToUpper();//    ObjectText += ItemText + " "; if (ItemText.Contains(FindText.ToUpper())) { ok = true; //      } } } if (ok)//     { List<int> path2 = new List<int>(); path2.AddRange(path); ret.Add(new NamedObject() { Name = ObjectText, Item = Item, Path = path2 });//     } if (subItemsPath != null)//      { IEnumerable subItems=Item.GetObjectSubItem(subItemsPath) as IEnumerable; if (subItems != null) { List<int> path1 = new List<int>(); path1.AddRange(path); ret.AddRange(FindObjectByPropertyNames(subItems, path1)); } } i++; } return ret; }
      
      





これは、検索テキストを含むすべての要素の検索方法です。

 int failCount; //   //    void SelectNodeByPath(ItemsControl control, IEnumerable<int> path) { List<int>L= path.ToList<int>(); if (L.Count == 0) { return; } if (control.Items.Count > L[0]) { do //         { control.UpdateLayout(); } while (control.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated); TreeViewItem dObject = control.ItemContainerGenerator.ContainerFromIndex(L[0]) as TreeViewItem; if (dObject == null)//       { dObject = GetTreeViewItem(control, L [0]); } if (dObject == null) { MessageBox.Show("   ); } else //  { L.RemoveAt(0); if (L.Count == 0) //       { dObject.IsSelected = true; dObject.BringIntoView(); } else //        { dObject.IsExpanded = true; SelectNodeByPath(dObject, L); //   } } } else { MessageBox.Show(" "+control.Items.Count+"   > "+L[0]); } }
      
      







GetTreeViewItem関数(コントロール、L [0]); 信頼できる結び目を確実に見つけることができます

大変混乱しています。 指定されたサイトのコードに基づきます。

blogs.msdn.com/b/wpfsdk/archive/2010/02/23/finding-an-object-treeviewitem.aspx

これが新しいコードです。

myTreeViewWith search.zip

検索は別のスレッドで機能します。



ユーザーが検索するプロパティを選択できるように、高度な検索を行うことができます

そして...しかし、これは装飾であり、アイデアは機能します。

PS投稿の著者である私の兄弟SergejSh-それに関するすべての質問とコメント。



All Articles