2016-01-08 30 views
1

如何通過編程設置將NewTableList.Items元素的「Header」屬性綁定到TableModel.TABLE_NAME?以編程方式將TreeViewItem綁定到自定義對象列表

foreach (SchemaModel schema in connection.schemas) 
{ 
TreeViewItem newSchema = new TreeViewItem() 
{ 
    Header = schema.SCHEMA_NAME.ToString() 
}; 
Binding newTableBinding = new Binding();  
newTableBinding.Source = schema.tables; 

TreeViewItem newTableList = new TreeViewItem() 
{ 
     Header = "Tables", 
}; 

BindingOperations.SetBinding(newTableList, TreeViewItem.ItemsSourceProperty, newTableBinding); 

newSchema.Items.Add(newTableList); 
newTVI.Items.Add(newSchema); 

} 

我老了,速度很慢的代碼看起來像這樣:

foreach (TableModel table in schema.tables) 
{ 
    newTableList.Items.Add(new TreeViewItem() 
    { 
     Header = table.TABLE_NAME.ToString() 
    }); 
} 

老話題(爲了更好的VIEW)

我嘗試建立自定義的TreeView和改變我的「非常緩慢的方法「用綁定到自定義對象列表的速度最快。

我有SchemaModel其中包含

List<TableModel> tables 

,每個TableModel中有

string TABLE_NAME. 

我以前很慢的方法:

/* VERY SLOW METHOD !!! */ 
//foreach (TableModel table in schema.tables) 
//{ 
// newTableList.Items.Add(new TreeViewItem() 
// { 
//  Header = table.TABLE_NAME.ToString() 
// }); 
//} 

每次都創建樹型視圖減慢我的UI,其我無法修復多任務。

我決定以編程方式綁定到TableModels這樣的名單:

Binding newTableBinding = new Binding(); 
newTableBinding.Source = schema.tables; 

TreeViewItem newTableList = new TreeViewItem() 
{ 
    Header = "Tables", 
    // ItemsSource = schema.tables // also works 
}; 
BindingOperations.SetBinding(newTableList, TreeViewItem.ItemsSourceProperty, newTableBinding); 

我怎麼能綁定Header屬性爲「TABLE_NAME」基於schema.tables列表中的項目?

我完整的代碼

代碼:

foreach (ConnectionModel connection in aliases) 
{ 
    TreeViewItem newTVI = new TreeViewItem() { Header = connection.alias.ToString() }; 

    foreach (SchemaModel schema in connection.schemas) 
    { 
     TreeViewItem newSchema = new TreeViewItem() { Header = schema.SCHEMA_NAME.ToString() }; 

     Binding newTableBinding = new Binding(); 
     newTableBinding.Source = schema.tables; 
     // newTableBinding.Path = new PropertyPath("TABLE_NAME"); 

     TreeViewItem newTableList = new TreeViewItem() 
     { 
      Header = "Tables", 
      // ItemsSource = schema.tables 
     }; 
     BindingOperations.SetBinding(newTableList, TreeViewItem.ItemsSourceProperty, newTableBinding); 

     TreeViewItem newIndexList = new TreeViewItem() { Header = "Indexes" }; 

     /* VERY SLOW METHOD !!! */ 
     //foreach (TableModel table in schema.tables) 
     //{ 
     // newTableList.Items.Add(new TreeViewItem() 
     // { 
     //  Header = table.TABLE_NAME.ToString() 
     // }); 
     //} 

     newSchema.Items.Add(newTableList); 
     newSchema.Items.Add(newIndexList); 
     newTVI.Items.Add(newSchema); 
    } 
    tmpAliasTree.Items.Add(newTVI); 
} 

tmpAliasTree是我的TreeView。

我ConnectionModel

[Serializable()] 
public class ConnectionModel 
{ 

    private int _id; 

    private string _dsn; 
    private string _alias ; 

    private string _host ; 
    private string _port ; 

    private string _database; 

    private string _username; 
    private string _password; 

    public List<SchemaModel> schemas = new List<SchemaModel>(); 

    } 

我SchemaModel

[Serializable()] 
public class SchemaModel 
{ 
    [System.Xml.Serialization.XmlElement("SCHEMA_NAME")] 
    public string SCHEMA_NAME { get; set; } = ""; 

    [XmlArray("tables"), XmlArrayItem("TableModel", typeof(TableModel), ElementName = "TableModel")] 
    public List<TableModel> tables = new List<TableModel>(); 

} 

我的TableModel

[Serializable()] 
public class TableModel 
{ 
    [System.Xml.Serialization.XmlElement("TABLE_CAT")] 
    public string TABLE_CAT  { get; set; } = ""; 
    [System.Xml.Serialization.XmlElement("TABLE_SCHEM")] 
    public string TABLE_SCHEM { get; set; } = ""; 
    [System.Xml.Serialization.XmlElement("TABLE_NAME")] 
    public string TABLE_NAME { get; set; } = ""; 
    [System.Xml.Serialization.XmlElement("TABLE_TYPE")] 
    public string TABLE_TYPE { get; set; } = ""; 
    [System.Xml.Serialization.XmlElement("REMARKS")] 
    public string REMARKS  { get; set; } = ""; 
} 

謝謝你有任何建議。

+0

你的模型ISN」 t太糟糕了,但是你的模型應該[實現INotifyPropertyChanged](http://stackoverflow.com/a/1316417/424129),他們應該使用ObservableCollection而不是List。從代碼隱藏中刪除所有的TreeView代碼,然後在XAML中使用Bindings和模板來完成該部分。這應該可以幫助您在XAML部分開始:http://stackoverflow.com/questions/5894650/wpf-hierarchicaldatatemplate-treeview?rq=1 –

+0

@Ed賓吉:我爲什麼要使用的ObservableCollection? – Wiktor

+1

因爲當您添加或刪除「ObservableCollection」中的項目時,它會通知XAML控件。列表不這樣做。這與實現'INotifyPropertyChanged'的原因相同,當屬性值更改時通知XAML。 –

回答

0

雖然我同意,你應該考慮你的視圖定義移動到XAML,就可以實現你利用ItemsControl.ItemContainerStyle財產(包括TreeViewTreeViewItemItemsControl得出)問。基本上,您需要定義一個定位爲TreeViewItem的樣式,併爲值爲TreeViewItem.HeaderProperty的設置器添加適當的綁定,然後將該樣式分配給您的樹形視圖或特定項目(取決於您的需要)。這裏有一個例子:

TreeViewItem newTVI = new TreeViewItem() { Header = connection.alias.ToString() }; 
var tableModelItemStyle = new Style(typeof(TreeViewItem)); 
tableModelItemStyle.Setters.Add(new Setter 
{ 
    Property = TreeViewItem.HeaderProperty, 
    //since items will present instances of TableModel, the DataContext will hold 
    //the model, so we can define the binding using only the property name 
    Value = new Binding("TABLE_NAME"), 
}); 
foreach(...) 
{ 
    ... 
    TreeViewItem newTableList = new TreeViewItem 
    { 
     ... 
     ItemContainerStyle = tableModelItemStyle, 
    }; 
    ... 
} 

如果你想設置的樣式在樹視圖中的所有項目(我不推薦),你可以像這樣:

newTVI.ItemContainerStyle = tableModelItemStyle; 
+0

非常感謝。 這正是我所需要的。 – Wiktor

相關問題