我通常能够用大约五分钟的搜索来解决我的问题,但是这个问题已经花费了几天没有结果,所以我会试着提出这个问题。
我有一个Form,其DataContext被设置为一个数据表(更喜欢LINQ to SQL,但我很难与Sybase相比,它缺乏对现代实体框架的良好支持。)我有一个组合框来自另一个应该更新的数据表表单数据表上的列,但我似乎无法获得SelectedValue绑定正常工作。
我的输出窗口中出现绑定错误,我不确定如何解决,但它指出了问题的原因:
System.Windows.Data错误:40:BindingExpression路径错误:'object'''DataTable'(HashCode = 1796783)'上找不到'color'属性。 BindingExpression:路径=颜色; DataItem ='DataTable'(HashCode = 1796783); target元素是'ComboBox'(Name ='cboColor'); target属性是'SelectedValue'(类型'Object')
我已经创建了一个示例应用,可以重新创建问题并在此处提供Xaml和代码
提前感谢您的帮助
<Window x:Class="WPFTestBed.ComboTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboTest" Height="300" Width="300"
Loaded="OnLoad">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="126*" />
<ColumnDefinition Width="152*" />
</Grid.ColumnDefinitions>
<DataGrid AutoGenerateColumns="False" Height="243" Margin="8,6,0,0" Name="dgList" VerticalAlignment="Top" CanUserAddRows="False" ItemsSource="{Binding}" SelectionChanged="dgList_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" IsReadOnly="True" Binding="{Binding Path=name}" Width="*"/>
<DataGridTextColumn Header="Color" IsReadOnly="True" Binding="{Binding Path=color}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Column="1" Height="207" HorizontalAlignment="Left" Margin="6,6,0,0" Name="grdSelection" VerticalAlignment="Top" Width="140" DataContext="{Binding}">
<TextBlock Height="23" HorizontalAlignment="Left" Margin="6,6,0,0" Name="textBlock1" Text="{Binding Path=name}" VerticalAlignment="Top" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="6,27,0,0" Name="textBlock2" Text="{Binding Path=color}" VerticalAlignment="Top" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="6,56,0,0" Name="cboColor" VerticalAlignment="Top" Width="120"
ItemsSource="{Binding}" DisplayMemberPath="colorName" SelectedValuePath="colorName" SelectedValue="{Binding Path=color}" />
</Grid>
<Button Content="_Save" Grid.Column="1" Height="23" HorizontalAlignment="Right" Margin="0,0,6,12" Name="btnSave" VerticalAlignment="Bottom" Width="75" Click="btnSave_Click" />
</Grid>
代码
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.Shapes;
using System.Data;
namespace WPFTestBed
{
/// <summary>
/// Interaction logic for ComboTest.xaml
/// </summary>
public partial class ComboTest : Window
{
public ComboTest()
{
InitializeComponent();
}
private DataTable getList()
{
DataTable dt = new DataTable();
DataRow row;
dt.Columns.Add(new DataColumn("name"));
dt.Columns.Add(new DataColumn("color"));
row = dt.NewRow(); row["name"] = "abe"; row["color"] = "Red"; dt.Rows.Add(row);
row = dt.NewRow(); row["name"] = "bob"; row["color"] = "Yellow"; dt.Rows.Add(row);
row = dt.NewRow(); row["name"] = "chuck"; row["color"] = "Blue"; dt.Rows.Add(row);
row = dt.NewRow(); row["name"] = "doug"; row["color"] = "Red"; dt.Rows.Add(row);
row = dt.NewRow(); row["name"] = "eddie"; row["color"] = "Yellow"; dt.Rows.Add(row);
row = dt.NewRow(); row["name"] = "fred"; row["color"] = "Blue"; dt.Rows.Add(row);
return dt;
}
private DataTable getColors()
{
DataTable dt = new DataTable();
DataRow row;
dt.Columns.Add(new DataColumn("colorName"));
row = dt.NewRow(); row["colorName"] = "Red"; dt.Rows.Add(row);
row = dt.NewRow(); row["colorName"] = "Yellow"; dt.Rows.Add(row);
row = dt.NewRow(); row["colorName"] = "Blue"; dt.Rows.Add(row);
return dt;
}
private void OnLoad(object sender, RoutedEventArgs e)
{
dgList.DataContext = getList();
cboColor.DataContext = getColors();
}
private void dgList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Get the selected Item
DataRowView selectedRow = (DataRowView)dgList.SelectedCells[0].Item;
//For Illustrative purposes - in "real life" the data table used for the DataContext would come from the database
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("name"));
dt.Columns.Add(new DataColumn("color"));
DataRow row = dt.NewRow(); row["name"] = selectedRow["name"].ToString(); row["color"] = selectedRow["color"]; dt.Rows.Add(row);
// Set the data context for the form
grdSelection.DataContext = dt;
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
DataTable dt = (DataTable)grdSelection.DataContext;
// dt is not updated by combobox binding as expected
}
}
}
答案 0 :(得分:0)
您的ComboBox SelectedValue绑定应绑定到colorName。
XAML:
<ComboBox Height="23" HorizontalAlignment="Left" Margin="6,56,0,0" Name="cboColor"
VerticalAlignment="Top" Width="120" ItemsSource="{Binding}"
DisplayMemberPath="colorName" SelectedValuePath="colorName"
SelectedValue="{Binding Path=colorName}" />
答案 1 :(得分:0)
问题在于,当您将列表绑定到颜色时,数据上下文会搞砸:
cboColor.DataContext = getColors();
需要将ComboBox的数据上下文绑定到DataTable。在示例应用程序中,您可以通过直接设置项目源并单独保留其数据上下文来实现:
cboColor.ItemsSource = getColors().AsDataView();