如何将控件绑定到 WPF 列表视图列
我是 WPF 新手,所以如果我错过了一些明显的东西,请原谅我,
我有以下列表视图控件(为简洁起见,删除了不相关的详细信息)
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Type" DisplayMemberBinding="{Binding Type}"/>
<GridViewColumn Header="Details" DisplayMemberBinding="{Binding Details}"/>
</GridView>
</ListView.View>
</ListView>
我在代码后面将项目添加到此列表视图
public void Add(LogEntry entry)
{
ListViewItem item = new ListViewItem();
item.Content = entry;
listView.Items.Add(item);
}
,其中 LogEntry 具有“Type”的公共字符串属性”和“细节”
到目前为止,一切都很好,一切都很好,但是.. 我希望我的详细信息属性本身就是一个元素(包含各种类型内容的 TextBox 或 DockPanel) 如何将此元素绑定到列表列?
使用上面的代码,将“详细信息”更改为元素,我只需在列表框中获取类名称(例如 System.Windows.Control.TextBox),因为默认情况下单元格显示属性的 ToString() 值。 我在谷歌上搜索了使用 DataTemplate 的示例,但找不到将元素绑定到面板内容的示例。 控件无法在 xaml 中定义,因为它的结构和内容直到运行时才知道
绑定是一种方式(我只需要显示列表,不需要更新底层数据结构)
为了使我的问题更清楚,我想绑定以下内容列表项
class LogEntry
{
public string Type {get;}
public DockPanel Details {get;} // This dock panel was created by code and contains
// various elements not predictable at compile time
}
I'm new to WPF so forgive me if I've missed something obvious
I have the following list view control (non relevent details removed for brevity)
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Type" DisplayMemberBinding="{Binding Type}"/>
<GridViewColumn Header="Details" DisplayMemberBinding="{Binding Details}"/>
</GridView>
</ListView.View>
</ListView>
I add items to this list view in code behind
public void Add(LogEntry entry)
{
ListViewItem item = new ListViewItem();
item.Content = entry;
listView.Items.Add(item);
}
where LogEntry has public string properties for "Type" and "Details"
So far, so good, all works lovely but..
I want my details property to be an element itself (TextBox or DockPanel containing various types of content)
How can I bind this Element to the list column?
Using the code above, Changing "Details" to an element I simply get the class name in the list box (e.g. System.Windows.Control.TextBox) as by default the cell displays the ToString() value of the property.
I have googled examples which use a DataTemplate but I can't find an example of binding an element to the content of a panel.
The control cannot be defined in xaml as its structure and contents are not known until runtime
The binding is one way (I only need to display the list, not update the underlying data structure)
To make my problem clearer, I want to bind the following list item
class LogEntry
{
public string Type {get;}
public DockPanel Details {get;} // This dock panel was created by code and contains
// various elements not predictable at compile time
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的模型(
LogEntry
类)不应引用 UI 控件。相反,它应该包含 UI 所需的数据,并且 XAML 应该定义使用该数据的 DataTemplate。例如,您提到
LogEntry
中的 DockPanel 创建了运行时未知的项目。你能举个例子吗?在大多数情况下,数据中应该有某种模式,并且可以使用 DataTemplates 来定义如何绘制每个细节部分。如果您确实需要在模型中存储控件,那么您可以在
DataGridTemplateColumn
中使用ContentControl
并将其Content
设置为等于详细信息Your Model, the
LogEntry
class, should not reference a UI control. Instead it should contain the data needed by the UI, and the XAML should define a DataTemplate that uses that data. For example,You mentioned that the DockPanel in the
LogEntry
created items that were not known at runtime. Can you give an example of that? In most cases, you should have some kind of pattern in the data, and you can useDataTemplates
to define how to draw each Detail piece.If you REALLY need to store a control in the Model, then you can use a
ContentControl
in yourDataGridTemplateColumn
and set it'sContent
equal to the Details抱歉,我不能给你一个确切的答案,因为我没有 VS,我现在在这里,但有一些提示。
首先,您不想使用您的方法添加 Listview 项目,而是希望使用您的数据创建 ObservableCollection。然后您可以将列表视图的 itemssource 绑定到 observableCollection。
接下来,您可以为包含所需控件的列表视图创建一个项目模板,非常简单的事情就像具有水平方向和两个文本框的堆栈面板。
完成此操作后,因为您已将列表视图的 itemsource 设置为 ObservableCollection,所以您只需将文本框绑定到集合中的 String 属性即可。
请注意,ObservableCollection 比 List 更适合绑定,因为 ObservableCollection 支持 NotifyPropertyChanged()。
Sorry I cant give you an exact answer as I dont have VS where I am right now here but a few pointers.
First instead of using your method to add Listview items you want to create an ObservableCollection with your data. Then you can bind the itemssource of your listview to the observableCollection.
Next you can create an itemtemplate for the listview containing the control you want, something quite simple would be like a stack panel with horizontal orientation and two textboxes.
Once you have done that because you have set the itemsource of the listview to the ObservableCollection you can just bind the textbox to the String property within your collection.
Note that ObservableCollection is better to bind to than List as ObservableCollection supports NotifyPropertyChanged().
我已将您的代码复制到一个新项目中,并创建了相同的列表视图,这里是代码。这个可以正常工作并正确显示数据
XAML:
ViewModel:
I have copied your code into a new project and created the same list view here is the code. And this one worked and displayed to data correctly
XAML:
ViewModel: