我有一个绑定到XDocument的ComboBox,它不会写回值更改:
teams.xml
<?xml version="1.0" encoding="utf-8" ?>
<teams>
<team>
<name>Team A</name>
<leader>C</leader>
<members>
<member>A</member>
<member>B</member>
<member>C</member>
</members>
</team>
<team>
<name>Team B</name>
<leader>B</leader>
<members>
<member>B</member>
<member>D</member>
<member>E</member>
</members>
</team>
</teams>
MainWindow.xaml
<Window x:Class="Teamleader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<DataGrid Name="grid" ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Team" Binding="{Binding Path=Element[name].Value}"></DataGridTextColumn>
<DataGridTemplateColumn Header="Leader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=Element[members].Descendants, PresentationTraceSources.TraceLevel=High}"
SelectedValue="{Binding Path=Element[leader].Value, PresentationTraceSources.TraceLevel=High, Mode=TwoWay}"
SelectedValuePath="Value"
DisplayMemberPath="Value"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Leader Text (only for testing)" Binding="{Binding Path=Element[leader].Value, Mode=TwoWay}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="Save" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="SaveButton_Click" />
</Grid>
</Window>
MainWindow.xaml.cs
namespace Teamleader
{
public partial class MainWindow : Window
{
private XDocument doc;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
doc = XDocument.Load("teams.xml");
var teams = from team in doc.Root.Descendants("team") select team;
grid.DataContext = teams.ToList();
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
doc.Save("teams-output.xml");
}
}
}
当我通过单击更改ComboBox的SelectedItem时,我的OutputWindow向我显示以下四行:
System.Windows.Data信息:41:BindingExpression路径错误: 为'对象'找不到'值'属性,因为数据项为空。 这可能是因为数据提供者没有生成任何数据 然而。 BindingExpression:路径=值;的DataItem = NULL;目标元素是 'ComboBox'(Name =''); target属性是'NoTarget'(类型'Object')
System.Windows.Data信息:20:BindingExpression不能 由于缺少信息而检索值。 BindingExpression:路径=值;的DataItem = NULL;目标元素是 'ComboBox'(Name =''); target属性是'NoTarget'(类型'Object')
System.Windows.Data信息:21:BindingExpression不能 从null数据项中检索值。绑定时可能会发生这种情况 分离或绑定到没有值的Nullable类型时。 BindingExpression:路径=值;的DataItem = NULL;目标元素是 'ComboBox'(Name =''); target属性是'NoTarget'(类型'Object')
System.Windows.Data信息:10:无法使用获取值 绑定并且不存在有效的回退值;使用默认值。 BindingExpression:路径=值;的DataItem = NULL;目标元素是 'ComboBox'(Name =''); target属性是'NoTarget'(类型'Object')
当我更改ComboBox的SelectedItem时,相应的TextBox不会更改其值。当我更改TextBox中的值时,ComboBox立即适应(假设值在列表中)。此外,使用TextBox更改的值将写回XDocument。使用ComboBox更改值无效。
我的目标框架是.NET Framework 4.5,我的系统运行的是Windows7 x64。
我找到了ComboBox twoway binding with XElement,但是上面提到的修补程序适用于.NET 4.0 - 我想现在应该修复它。安装此修补程序不适用于我的系统。
我还找到了ComboBox.SelectedValue not updating from binding source。使用SelectedItem而不是SelectedValue给我一个System.InvalidOperationException
告诉我,TwoWay或OneWayToSource绑定不能在只读属性'Item'上工作(类型为MS.Internal.Xml.Linq.ComponentModel.XDeferredSingleton)。
任何人都可以指出我的错误或告诉我.NET Framework 3.5中的错误是否仍然存在?
答案 0 :(得分:1)
问题WPF ComboBox not updating source确实告诉我该怎么做。将UpdateSourceTrigger=PropertyChanged
添加到我的SelectedValue绑定中可以解决问题:
<ComboBox ItemsSource="{Binding Path=Element[members].Descendants}"
SelectedValue="{Binding Path=Element[leader].Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
SelectedValuePath="Value"
DisplayMemberPath="Value"/>
我不知道为什么,但它就像一个魅力。
感谢“相关”-sidebar!
答案 1 :(得分:1)
UpdateSourceTrigger=PropertyChanged
仅适用于.NET&lt; 4.5和KB2328886或.NET 4.5及更高版本的修补程序。要使用没有此修补程序的旧框架修复此问题,请尝试此操作以手动触发所需的事件:
<ComboBox ItemsSource="{Binding Path=Element[ActionOptions].Descendants}"
SelectedValue="{Binding Path=Element[CurrentActionOption].Value, Mode=TwoWay}"
SelectedValuePath="Value"
SelectionChanged="SelectedIndexChanged"
DisplayMemberPath="Value"
Visibility="{Binding Path=Element[ActionOptionsVisibility].Value}"/>
private void SelectedIndexChanged(object sender, RoutedEventArgs e)
{
var bindingExpression = ((ComboBox)sender).GetBindingExpression(ComboBox.SelectedValueProperty);
bindingExpression.UpdateSource();
}