C# 以编程方式将TreeViewItem绑定到自定义对象列表
如何以编程方式将newTableList.Items元素的“Header”属性绑定到TableModel.TABLE\u名称C# 以编程方式将TreeViewItem绑定到自定义对象列表,c#,wpf,binding,treeview,C#,Wpf,Binding,Treeview,如何以编程方式将newTableList.Items元素的“Header”属性绑定到TableModel.TABLE\u名称 foreach (SchemaModel schema in connection.schemas) { TreeViewItem newSchema = new TreeViewItem() { Header = schema.SCHEMA_NAME.ToString() }; Binding newTableBinding = new Bin
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()
});
}
旧主题(为了更好地查看)
[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; } = "";
}
我尝试构建自定义TreeView,并使用绑定到自定义对象列表的fastest更改我的“非常慢的方法”
我有一个SchemaModel,它包含
List<TableModel> tables
我以前非常缓慢的方法是:
/* VERY SLOW METHOD !!! */
//foreach (TableModel table in schema.tables)
//{
// newTableList.Items.Add(new TreeViewItem()
// {
// Header = table.TABLE_NAME.ToString()
// });
//}
每次创建TreeViewItem都会减慢我的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);
如何将基于schema.tables列表的项的Header属性绑定到“TABLE_NAME”
我的完整代码
代码:
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是我的树视图
我的连接模型
[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>();
}
谢谢您的任何建议。
< P>虽然我同意您应该考虑将视图定义移动到XAML,但是您可以通过使用<代码> ITEMsCube实现您的请求。ItMeCuleStult属性(无论是代码> TreVIEW 和<代码> TreVIEWITEM 源于TreeViewItem
的样式,并为TreeViewItem.HeaderProperty
添加一个setter,其值具有适当的绑定,然后将该样式指定给树视图或特定项(取决于您的需要)。下面是一个例子:
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;
尽管我同意您应该将您的视图定义移到XAML,但是您可以利用<代码> ITEMsCube实现您的请求。ItMeCuleStult属性(无论是代码> TeeVIEW 和<代码> TreVIEWITEM源于<代码> ITEMsStase<代码>。基本上,您需要定义一个针对
TreeViewItem
的样式,并为TreeViewItem.HeaderProperty
添加一个setter,其值具有适当的绑定,然后将该样式指定给树视图或特定项(取决于您的需要)。下面是一个例子:
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;
你的模型还不错,但是你的模型应该,而且他们应该为孩子们使用ObservableCollection,而不是List。从codebehind中删除所有TreeView代码,并改为使用XAML中的绑定和模板。这应该可以帮助您开始学习XAML部分:@Ed Plunkett:为什么我应该使用ObservableCollection?因为当您在
ObservableCollection
中添加或删除项目时,它会通知XAML控件。列表不能做到这一点。这与您实现INotifyPropertyChanged
,以在属性值更改时通知XAML的原因相同。您的模型还不错,但您的模型应该,并且它们应该为子级使用ObservableCollection,而不是List。从codebehind中删除所有TreeView代码,并改为使用XAML中的绑定和模板。这应该可以帮助您开始学习XAML部分:@Ed Plunkett:为什么我应该使用ObservableCollection?因为当您在ObservableCollection
中添加或删除项目时,它会通知XAML控件。列表不能做到这一点。这与您实现INotifyPropertyChanged
,在属性值更改时通知XAML的原因相同。非常感谢。这正是我需要的。非常感谢。这正是我所需要的。