使用 LINQ XML 绑定 ComboBox
Posted
技术标签:
【中文标题】使用 LINQ XML 绑定 ComboBox【英文标题】:Binding ComboBox with LINQ XML 【发布时间】:2011-01-21 12:55:44 【问题描述】:对不起,我的英语很差,那不是我的母语。
我是 WPF 和 LINQ 的初学者(从 3 天开始),并且是 C# 的临时用户。
昨天,我整天都在努力解决我的问题并阅读了几个文档,但我的代码中的一个错误仍然存在。
我将 XElement 传递给绑定其内容的控件,但我有一个但在 ComboBox 中
这是 XElement 的 XML:
<racine>
<element nom="Element 1">
<rubrique nom="Element 1 - rubrique 1">
<etat valeur="Hors service">
<option valeur="En service" />
<option valeur="Hors service service" />
</etat>
<observation>lorem ipsum</observation>
</rubrique>
<rubrique nom="Element 1 - rubrique 2">
<etat>
</etat>
<observation>titi toto</observation>
</rubrique>
</element>
<element nom="Element 2">
<rubrique nom="Element 2 - rubrique 1">
<etat valeur="foo">
</etat>
<observation>youpi</observation>
</rubrique>
<rubrique nom="Element 2 - rubrique 2">
<etat valeur="bar">
<option valeur="En service" />
</etat>
<observation></observation>
</rubrique>
</element>
</racine>
这是我的控件 MonControle.xaml.cs 背后的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace MonProjet.Controles
/// <summary>
/// Logique d'interaction pour MonControle.xaml
/// </summary>
public partial class MonControle : UserControl
XElement xRacine;
ObservableCollection<XElement> xElementsObservable = new ObservableCollection<XElement>();
public MonControle()
InitializeComponent();
DataContext = xElementsObservable;
#region Propriété Attribus
[Category("Configuration"), Browsable(false), Description("Element XML racine")]
public XElement xRacine
get
return xRacine;
set
this.xRacine = value;
MajXElementsObservable();
#endregion
private void MajXElementsObservable()
var requette = from xElements in xRacine.Descendants("element")
select (XElement)xElements;
xElementsObservable.Clear();
foreach (XElement xElement in requette)
xElementsObservable.Add(xElement);
这里是 MonControle.xaml 的 xaml:
<UserControl x:Class="MonProjet.Controles.MonControle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="Auto" Width="Auto">
<!--
http://www.youdev.net/post/2008/09/23/WPF-SplitContainer-2.aspx
http://www.youdev.net/post/2009/03/19/WPF-SplitContainer-Part-2.aspx
-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*"/>
<ColumnDefinition Width="Auto" MinWidth="4"/>
<ColumnDefinition Width="75*"/>
</Grid.ColumnDefinitions>
<DockPanel Grid.Column="0" LastChildFill="True">
<ListBox Name="lbxElements" ItemsSource="Binding UpdateSourceTrigger=PropertyChanged" DisplayMemberPath="Attribute[nom].Value" />
</DockPanel>
<GridSplitter Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="4" VerticalAlignment="Stretch"/>
<DockPanel Grid.Column="2" LastChildFill="True" DataContext="Binding Path=SelectedItem.Elements[rubrique], ElementName=lbxElements, UpdateSourceTrigger=PropertyChanged">
<ListBox ItemsSource="Binding UpdateSourceTrigger=PropertyChanged"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<GroupBox Header="Binding Path=Attribute[nom].Value">
<StackPanel Orientation="Horizontal">
<!-- http://***.com/questions/561166/binding-wpf-combobox-to-a-custom-list -->
<ComboBox MinWidth="75" IsEditable="True"
ItemsSource="Binding Path=Element[etat].Elements[option], UpdateSourceTrigger=PropertyChanged"
DisplayMemberPath="Attribute[valeur].Value"
SelectedValuePath="Attribute[valeur].Value"
SelectedValue="Binding Path=Element[etat].Element[option].Attribute[valeur].Value"
/>
<TextBox MinWidth="150" AcceptsReturn="False" AcceptsTab="False" TextWrapping="NoWrap"
Text="Binding Path=Element[observation].Value, UpdateSourceTrigger=PropertyChanged" />
</StackPanel>
</GroupBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Grid>
</UserControl>
我的问题是:
控件加载的时候还可以,但是 如果我在元素之间切换 left ListBox,ComboBox的值 改变...尝试很多事情,做很多事情 测试,但不可能修复它!
无法输入没有的值 在列表中,但我想要 能够做到。同样,我做了很多 测试,但我无法解决问题
最后但同样重要的是:我想升职 ObservableCollection 时的事件 更改为写入 XML 文件, 但不可能赶上一个事件...... 我试过类似的东西 xElementsObservable.CollectionChanged += 新的 NotifyCollectionChangedEventHandler(XElementsObservable_CollectionChanged); 但它不起作用......
提前感谢您的帮助!
【问题讨论】:
【参考方案1】:这很难,但我有解决我所有问题的方法!
这里是解决方案:
第一时间,ComboBox XAML 必须如下所示:
<ComboBox MinWidth="75" IsEditable="True"
IsSynchronizedWithCurrentItem="False"
ItemsSource="Binding Path=Element[etat].Elements[option]"
DisplayMemberPath="Attribute[valeur].Value"
Text="Binding Element[etat].Attribute[valeur].Value, UpdateSourceTrigger=PropertyChanged"
/>
这个回答问题1和2:当我们关注包含的节点的属性“valeur”的值时,我们可以写我们想要的,即使我们写的值不在集合中,并且, ComboBox文本中节点显示的问题解决了!
对于问题 3,我的错误是我专注于可观察的集合!
但是,解决方案很简单,我在 XDocument 上附加了一个“已更改”事件,其中包含我在此处操作的所有 XElement!
所以,我把这段代码放在我软件的主窗口中:
private void InitPerso()
xDoc = XDocument.Load(@"C:\fichier.xml");
xDoc .Changed += new EventHandler<XObjectChangeEventArgs>(XDoc_Changed);
private void XEdls_Changed(object sender, XObjectChangeEventArgs e)
xDoc .Save(@"C:\fichier.xml");
等等!
对不起,我的英语不好,我希望这会有所帮助......
【讨论】:
以上是关于使用 LINQ XML 绑定 ComboBox的主要内容,如果未能解决你的问题,请参考以下文章
使用 Linq (asp.net) 绑定 Gridview 数据源