2013-05-02 97 views
0

我有一個組合框綁定到的XDocument,並沒有寫回值的變化:雙向綁定的WPF組合框的XDocument

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 Information: 41 : BindingExpression path error: 'Value' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=Value; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=Value; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=Value; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Value; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

當我改變ComboBox的的SelectedItem,相應的文本框不會改變它的值。當我更改文本框中的值時,組合框立即適應(假設值在列表中)。此外,通過使用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

是不是延遲加載的問題?部分錯誤消息顯示「這可能會發生,因爲數據提供者尚未產生任何數據。」?在將列表分配給Datacontext之前,嘗試遍歷所有團隊和所有團隊領導。它有幫助嗎? – milanio 2013-05-02 13:14:47

+0

我沒有嘗試過。我現在認爲這些消息只是消息,並不重要。畢竟,當我添加'UpdateSourceTrigger = PropertyChanged'時,它可以工作,請參閱下面的答案。 – 2013-05-03 07:41:28

回答

0

問題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"/> 

我不知道爲什麼,但它的工作原理就像一個魅力。

感謝「相關」側欄!

1

UpdateSourceTrigger=PropertyChanged只適用於.NET < 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(); 
}