由於默認的TreeView不支持的SelectedItem綁定,你必須執行一個醜陋的解決方法。子類TreeView和使它可綁定第一:
public class TreeViewA : TreeView {
public new static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeViewA), new FrameworkPropertyMetadata(null, OnSelectedItemChanged));
public TreeViewA() {
base.SelectedItemChanged += this.OnTreeViewSelectedItemChanged;
this.ItemContainerGenerator.StatusChanged += this.ItemContainerGeneratorOnStatusChanged;
}
public new object SelectedItem {
get {
return this.GetValue(SelectedItemProperty);
}
set {
this.SetValue(SelectedItemProperty, value);
}
}
private void ItemContainerGeneratorOnStatusChanged(object sender, EventArgs eventArgs) {
if (this.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
return;
if (this.SelectedItem != null) {
this.VisualSelectItem();
}
}
private void VisualSelectItem() {
var xx = (TreeViewItem)this.ItemContainerGenerator.ContainerFromItem(this.SelectedItem);
if (xx == null)
return;
xx.IsSelected = true;
xx.BringIntoView();
}
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
this.SelectedItem = e.NewValue;
}
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
if (e.NewValue != null) {
(sender as TreeViewA)?.VisualSelectItem();
}
}
}
接下來,GUI(例)
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<local:TreeViewA ItemsSource="{Binding Documents}" SelectedItem="{Binding SelectedDocument, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<TreeView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Image Source="whereever" Width="40" Height="40"/>
<TextBlock Text="{Binding Name}"/>
</WrapPanel>
</DataTemplate>
</TreeView.ItemTemplate>
</local:TreeViewA>
<DataGrid Grid.Column="1" ItemsSource="{Binding SubDocuments, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Document Type Name" Binding="{Binding DocumentTypeName}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Status" Binding="{Binding Name}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Description" Binding="{Binding Description}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Type" Binding="{Binding Type}" IsReadOnly="True"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
我的例子模型文檔:我的例子中
public class Document {
public string Name {
get; set;
}
public string DocumentTypeName {
get; set;
}
public string Description {
get; set;
}
public string Type {
get; set;
}
}
代碼隱藏-Window:
public partial class Window1 : INotifyPropertyChanged {
public Window1() {
InitializeComponent();
this._docs.Add(new Document { Name = "Doc1", Type = "docx", Description = "Important Doc", DocumentTypeName = "Word-Document" });
this._docs.Add(new Document { Name = "Doc2", Type = "xlsx", Description = "Important Calculation", DocumentTypeName = "Excel-Document" });
this._docs.Add(new Document { Name = "Doc3", Type = "pdf", Description = "Important Contract", DocumentTypeName = "Pdf-Document" });
this.DataContext = this;
}
public Document SelectedDocument {
get {
return this._selectedDocument;
}
set {
if (Equals(value, this._selectedDocument))
return;
this._selectedDocument = value;
this.SubDocuments.Clear();
this.SubDocuments.Add(value);
this.OnPropertyChanged();
}
}
public ObservableCollection<Document> SubDocuments
{
get { return this._subDocuments; }
set
{
if (Equals(value, this._subDocuments)) return;
this._subDocuments = value;
this.OnPropertyChanged();
}
}
private readonly ObservableCollection<Document> _docs = new ObservableCollection<Document>();
private Document _selectedDocument;
private ObservableCollection<Document> _subDocuments = new ObservableCollection<Document>();
public ObservableCollection<Document> Documents => this._docs;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Closure
這段代碼應該爲您提供一個想法,它是如何完成的。它肯定不同於你的實際對象和實現。但既然你說過,你只需要朝正確的方向推進,這可能會給你一個Jumpstart。
注意
我已經使這個代碼隱藏和模型沒有實現INotifyPropertyChanged
,因爲它並不真正在這個例子中關係。
希望這會有所幫助。
針對你的陳述,在WPF中這樣做很簡單。你的煩惱在哪裏?你卡在哪裏?你已經嘗試過了什麼? – lokusking
@lokusking:編輯我的問題 – user575219