1

通常は 5 分程度の検索で問題を解決できますが、今回は結果が得られずに数日かかったので、質問してみます。

私は DataContext がデータテーブルに設定されているフォームを持っています (LINQ to SQL を好むでしょうが、最新のエンティティ フレームワークを十分にサポートしていない Sybase で立ち往生しています)。フォーム データ テーブルを作成しましたが、SelectedValue のバインドが正しく機能しないようです。

出力ウィンドウにバインド エラーが表示されます。解決方法がわかりませんが、問題の原因を示しています。

System.Windows.Data エラー: 40: BindingExpression パス エラー: 'object' ''DataTable' (HashCode=1796783)' に 'color' プロパティが見つかりません。BindingExpression: パス = 色; DataItem='DataTable' (HashCode=1796783); ターゲット要素は 'ComboBox' (Name='cboColor') です。ターゲット プロパティは '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
        }            
    }
}
4

2 に答える 2

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}" />
于 2012-05-05T19:58:39.200 に答える
0

問題は、リストを色にバインドすると、データ コンテキストが台無しになることです。

 cboColor.DataContext = getColors();

ComboBox のデータ コンテキストを DataTable にバインドしておく必要があります。サンプル アプリでは、アイテム ソースを直接設定し、そのデータ コンテキストをそのままにしておくことで実行できます。

cboColor.ItemsSource = getColors().AsDataView();
于 2012-05-05T20:08:27.753 に答える