将文本框绑定到使用LINQ to XML数据填充的组合框 [英] Binding Text Box to Combo Box populated with LINQ to XML data
问题描述
我无法弄清楚如何正确地将TextBox绑定到一个ComboBox,该ComboBox使用以下结构的XML文件填充数据:
I'm having trouble figuring out how to properly bind TextBoxes to a ComboBox that is populated with data from an XML file with the following structure:
<?xml version="1.0" encoding="utf-8"?>
<CustDB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer>
<Name />
<Address1 />
<Address2 />
<Phone />
<Fax />
<Cell />
<Other />
<Attn />
<Email />
<SalesPerson />
</Customer>
</CustDB>
我的绑定是通过LINQ to XML完成的:
My binding is done through LINQ to XML:
Dim dbXML As String = "..\custdbTesting.xml"
Dim contacts = XDocument.Load(dbXML, LoadOptions.PreserveWhitespace)
Dim custQuery = From customer In contacts.Elements("CustDB").Elements("Customer") _
Order By customer.Value Ascending _
Select Nm = customer.Elements("Name").Value, Ad1 = customer.Elements("Address1").Value, Ad2 = customer.Elements("Address2").Value _
, Ph = customer.Elements("Phone").Value, Fx = customer.Elements("Fax").Value, Ce = customer.Elements("Cell").Value _
, Oth = customer.Elements("Other").Value, Atn = customer.Elements("Attn").Value, Eml = customer.Elements("Email").Value _
, SaPe = customer.Elements("SalesPerson").Value
For Each result In custQuery
cbxName.Items.Add(result.Nm)
Next
<ComboBox x:Name="cbxName"/>
<TextBox x:Name="txbAdd1" Margin="0,23,0,0" Text="{Binding SelectedItem, ElementName=cbxName}"/>
有人可以帮我弄清楚我做错了什么吗?我正在使用Visual Studio 2012并通过TextBox属性docker添加绑定。我认为这是直截了当的,但不是这样。
Can someone please help me figure out what I am doing wrong? I am using Visual Studio 2012 and adding binding through the TextBox properties docker. I assumed this would be straight forward, but not so.
推荐答案
要做的步骤:
1)创建课程:
Steps to do:
1) Create class:
Public Class Customer
Private sName As String = String.Empty
Private sAddress1 As String = String.Empty
Private sAddress2 As String = String.Empty
Private sPhone As String = String.Empty
Private sFax As String = String.Empty
Private sCell As String = String.Empty
Private sOther As String = String.Empty
Private sAttn As String = String.Empty
Private sEmail As String = String.Empty
Private sSalesPerson As String = String.Empty
Public Property CustName As String
Get
Return sName
End Get
Set(value As String)
sName = value
End Set
End Property
Public Property Address1 As String
Get
Return sAddress1
End Get
Set(value As String)
sAddress1 = value
End Set
End Property
Public Property Address2 As String
Get
Return sAddress2
End Get
Set(value As String)
sAddress2 = value
End Set
End Property
Public Property Phone As String
Get
Return sAddress2
End Get
Set(value As String)
sAddress2 = value
End Set
End Property
Public Property Fax As String
Get
Return sFax
End Get
Set(value As String)
sFax = value
End Set
End Property
Public Property Cell As String
Get
Return sCell
End Get
Set(value As String)
sCell = value
End Set
End Property
Public Property Other As String
Get
Return sOther
End Get
Set(value As String)
sOther = value
End Set
End Property
Public Property Attn As String
Get
Return sAttn
End Get
Set(value As String)
sAttn = value
End Set
End Property
Public Property Email As String
Get
Return sEmail
End Get
Set(value As String)
sEmail = value
End Set
End Property
Public Property SalesPerson As String
Get
Return sSalesPerson
End Get
Set(value As String)
sSalesPerson = value
End Set
End Property
End Class
此类与xml结构具有相同的成员。
2)创建新界面以便能够使用类属性
This class has the same members as your xml structure.
2) Create new Interface to be able to use class properties
Public Interface ICustomer
'properties
Property Name As String
Property Address1 As String
Property Address2 As String
Property Phone As String
Property Fax As String
Property Cell As String
Property Other As String
Property Attn As String
Property Email As String
Property SalesPerson As String
End
了解有关界面的更多信息[ ^ ]
3)添加新模块。定义全局变量 Customers
,其中包含 Customer
的列表。创建过程/子例程以将数据从xml加载到 Customers
列表中。
Read more about Interfaces[^]
3) Add new module. Define global variable Customers
which holds the list of Customer
. Create procedure/subroutine to load data from xml into Customers
list.
Module ModMain
Public Customers As List(Of Customer) = Nothing
Sub LoadXmlData(sFileName As String)
Dim xDoc As XDocument = Nothing
Dim custList As IEnumerable = Nothing
Try
Customers = New List(Of Customer)
xDoc = XDocument.Load(sFileName, LoadOptions.PreserveWhitespace)
custList = From customer In xdoc.Elements("CustDB").Elements("Customer") _
Order By customer.Value Ascending _
Select Nm = customer.Elements("Name").Value, Ad1 = customer.Elements("Address1").Value, Ad2 = customer.Elements("Address2").Value _
, Ph = customer.Elements("Phone").Value, Fx = customer.Elements("Fax").Value, Ce = customer.Elements("Cell").Value _
, Oth = customer.Elements("Other").Value, Atn = customer.Elements("Attn").Value, Eml = customer.Elements("Email").Value _
, SaPe = customer.Elements("SalesPerson").Value
For Each c In custList
Dim cu As Customer = New Customer
With cu
.CustName = c.Nm
.Address1 = c.Ad1
.Address2 = c.Ad2
.Phone = c.Ph
.Fax = c.Fx
.Cell = c.Ce
.Other = c.Oth
.Attn = c.Atn
.Email = c.Eml
.SalesPerson = c.SaPe
End With
Customers.Add(cu)
Next
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Error...")
Finally
xDoc = Nothing
End Try
End Sub
End Module
请参阅: IEnumerable Interface [ ^ ]
4)点击此链接了解如何创建绑定上下文。
WPF中的简单数据绑定 [ ^ ] - 第2步
See: IEnumerable Interface[^]
4) follow this link to find out how to create binding context.
Simple Data Binding in WPF[^] - step 2
<TextBox Text="{Binding CustName}" Margin="10" Grid.Column="1"></TextBox>
CP KB更多内容:
WPF中数据绑定的一个非常简单的例子 [ ^ ]
5)最后,使用以下代码:
More at CP KB:
A Very Simple Example of Data Binding in WPF[^]
WPF Data Binding - Part 1[^]
5) Finally, use this code:
Class MainWindow
' on combobox selection change
Private Sub CustCombo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
Try
Dim cmb As ComboBox = sender
Dim i As Integer = cmb.SelectedIndex
Dim cust As Customer = Customers(i)
Me.DataContext = cust
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Error...")
End Try
End Sub
'new instance of window/application
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
'call LoadXmlData to fill global variable Customer as a List(of Customer)
Dim sFileName As String = "D:\custdbTesting.xml"
LoadXmlData(sFileName)
'fill combobox with customer names
For Each c As Customer In Customers
Me.CustCombo.Items.Add(c.CustName)
Next
End Sub
End Class
注意: 这是非常基本的样本。还有很多需要改进的地方,例如:您可以通过 xml序列化 [ ^ ]。
自定义类集合序列化和反序列化的完整示例 [ ^ ]
您可以在这里下载 [^] 一个完整的样本(不含xml)。
And最重要的:我强烈建议阅读 MSDN文档 [ ^ ]。
Note: This is very basic sample. There's a lot to improve, for example: you can load data from xml to class via xml serialization[^].
A Complete Sample of Custom Class Collection Serialization and Deserialization[^]
Here you can download[^] a complete sample (without xml).
And the most important: i strongly recommend to read MSDN documentation[^].
你在哪里调用数据加载代码?
我复制了你所有的代码,它就像一个魅力。当然我修改了文件路径,但我认为路径没问题,考虑到路径错误时会出现异常。
顺便问一下,是有没有机会错误地引用另一个 custdbTesting.xml 而不是你想要的那个?看来,你从目录项目目录/ bin 中的文件中读取。
我调用数据加载,当MainWindow是已加载:
Where do you call the data loading code?
I have copied all your code and it worked like a charm. Naturally I modified the file path, but I suppose that the path is OK for you, considering that an exception appear when you have wrong path.
By the way, is there any chance that by mistake you are referencing another custdbTesting.xml and not the one you want? It seems, that you read from a file that is in directory project directory/bin.
I call data loading, when the MainWindow is loaded:
<window x:class="MainWindow" xmlns:x="#unknown">
...
Loaded="Window_Loaded_1">
...
<!-- UI element definitions -->
</window>
和后面的代码:
and the code behind:
Private Sub Window_Loaded_1(sender As Object, e As RoutedEventArgs)
Dim dbXML As String = "../../custdbTesting.xml"
' File path to my test file in project folder
' Rest is the same you wrote
...
End Sub
这篇关于将文本框绑定到使用LINQ to XML数据填充的组合框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!