29

さまざまな 質問への回答を見てきましたが、解決しようとしている問題への回答の内容をマッピングすることができませんでした。私はそれを次のコード(私が達成しようとしている結果を表す)に減らしました、そして基本的に行が編集されていないときにPerson.TitleId対応するものとしてレンダリングできるようにしたいTitle.TitleText、そしてドロップダウンを持っていますTitleTextドロップダウンにsが表示され、変更されたときに関連TitleIdするレコードに書き戻されるように、正しくバインドされています。Person

<DataGridComboBoxColumn>要するに、これを達成するために私は何を入れますか?

App.xaml.cs

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    var viewModel = new ViewModels.MainWindowViewModel();
    var mainWindow = new MainWindow();
    mainWindow.DataContext = viewModel;
    mainWindow.ShowDialog();
}

MainWindow.xaml

<Grid>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Contacts}">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Title" SelectedItemBinding="{Binding Person}">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
                        <Setter Property="DisplayMemberPath" Value="TitleText" />
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Person.cs

public class Person
{
    public int TitleId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

Title.cs

public struct Title
{
    public Title(int titleId, string titleText)
        : this()
    {
        TitleId = titleId;
        TitleText = titleText;
    }

    public string TitleText { get; private set; }
    public int TitleId { get; private set; }

    public static List<Title> GetAvailableTitles()
    {
        var titles = new List<Title>();

        titles.Add(new Title(1, "Mr"));
        titles.Add(new Title(2, "Miss"));
        titles.Add(new Title(3, "Mrs"));

        return titles;
    }
}

MainWindowViewModel.cs

public class MainWindowViewModel : ViewModelBase
{
    private ObservableCollection<Person> contacts;
    private List<Title> titles;

    public MainWindowViewModel()
    {
        titles = Title.GetAvailableTitles();

        Contacts = new ObservableCollection<Person>();
        Contacts.Add(new Person() { FirstName = "Jane", LastName = "Smith", TitleId = 2 });
    }

    public List<Title> Titles
    {
        get { return titles; }
    }

    public ObservableCollection<Person> Contacts
    {
        get { return contacts; }
        set
        {
            if (contacts != value)
            {
                contacts = value;
                this.OnPropertyChanged("Contacts");
            }
        }
    }
}

ViewModelBase.cs

public class ViewModelBase : INotifyPropertyChanged
{
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
4

2 に答える 2

39

これが動作するコードです。ここでの重要なポイントは、SelectedValueBindingの代わりにを使用することでしSelecteItemBindingた。

<DataGridComboBoxColumn Header="Title" 
                        SelectedValueBinding="{Binding TitleId}"
                        SelectedValuePath="TitleId"
                        DisplayMemberPath="TitleText"
                        >
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
于 2011-04-01T20:17:23.027 に答える
2

@SnowBearの答えは私にとってうまくいきました。しかし、バインディングの詳細を明確にしたいと思います。

@Robの例では、TitleクラスとPersonクラスの両方がTitleIDを使用しています。したがって、@ SnowBearの回答では、バインディングでは次のようになります。

SelectedValueBinding="{Binding TitleId}"

どのクラスとプロパティがバインドされているかはすぐにはわかりませんでした。

SelectedValueBinding属性がDataGridComboBoxColumnに表示されたため、含まれているDataGridのItemsSourceにバインドされています。この場合、PersonオブジェクトのContactsコレクション。

私の場合、DataGridのDataSourceコレクションは、ComboBoxのItemSourceコレクションのValuePathとは異なる名前のプロパティに関連付けられていました。そのため、SelectedValueBindingの値は、ComboBoxのSelectedValuePathで指定されたプロパティとは異なるプロパティにバインドされました。

于 2012-10-18T19:24:54.870 に答える