0

各行DataGridのカスタムを使用して、いくつかのデータをに入れる必要があります。UserControlデータの表示は問題なく機能しますが、カスタムのフィールドを編集してもUserControl、バインドされたデータレコードは変更されません。

ListBox代わりにを使用してデータを表示すると、すべて期待どおりに機能します。しかし、私はむしろDataGridを使用したいと思います。これにより、新しいレコードの並べ替えと(できれば)追加が可能になります。

説明のために、これが私が表示(および編集)する必要のある単純なデータクラスです-人とその配偶者:

public class PersonViewModel : INotifyPropertyChanged
{
    public PersonViewModel(string name)
    {
        _name = name;
    }

    private string _name = null;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }

    private PersonViewModel _spouse = null;
    public PersonViewModel Spouse
    {
        get { return _spouse; }
        set
        {
            _spouse = value;
            this.PropertyChanged(this, new PropertyChangedEventArgs("Spouse"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };
}

..そしてここにカスタムUserControl(PersonView)があります:

<UserControl x:Class="TestDataGrid.PersonView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <!--Editing in DataGrid works only if these bindings use UpdateSourceTrigger=PropertyChanged-->
        <TextBox Text="{Binding Path=Name}" Width="70" />
        <TextBlock Text="is married to" Margin="6,0" Grid.Column="1" />
        <TextBox Text="{Binding Path=Spouse.Name}" Width="70" Grid.Column="2" />
    </Grid>
</UserControl>

最後に、すべてをまとめるためのメインウィンドウ(コードビハインド付き):

<Window x:Class="TestDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestDataGrid"
        Title="MainWindow" Height="350" Width="500">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <!--Changes made here correctly update the persons' names,
            and the changes are reflected in the DataGrid below-->
        <ListBox x:Name="_listbox" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <local:PersonView />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <!--Changes made here never reach the PersonViewModels..-->
        <DataGrid x:Name="_datagrid" Grid.Column="1" 
                  AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" />
                <DataGridTextColumn Binding="{Binding Path=Spouse.Name}" Header="Spouse" />
            </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow" >
                    <Setter Property="Template" >
                        <Setter.Value>
                            <ControlTemplate>
                                <local:PersonView />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
    </Grid>
</Window>

..。

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var personA = new PersonViewModel("Alice");
        var personB = new PersonViewModel("Barry");
        var personC = new PersonViewModel("Carl");
        var personD = new PersonViewModel("Doris");

        personA.Spouse = personB;
        personC.Spouse = personD;
        var persons = new List<PersonViewModel>() { personA, personC };

        _listbox.ItemsSource = persons;
        _datagrid.ItemsSource = persons;
    }

}

ListBoxの場合と同様に、DataGridで編集を機能させるにはどうすればよいですか?

4

1 に答える 1

2

私はあなたのコードを少しいじって、それが機能したと思います。

まず、PersonViewに、「DataGridでの編集は、これらのバインディングがUpdateSourceTrigger=PropertyChangedを使用する場合にのみ機能する」というメモがあります。UpdateSourceTriggerを設定する必要があることがわかりましたが、LostFocusを使用して、ListBoxと同じ動作を維持しようとしました。

<!--Editing in DataGrid works only if these bindings use UpdateSourceTrigger-->
    <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=LostFocus}" Width="70" />
    <TextBlock Text="is married to" Margin="6,0" Grid.Column="1" />
    <TextBox Text="{Binding Path=Spouse.Name, UpdateSourceTrigger=LostFocus}" Width="70" Grid.Column="2" />

次に、2つのDataGridTextColumnsとDataGrid.RowStyleを使用する代わりに、1つのDataGridTemplateColumnを使用しました。これが受け入れられることを願っています。以前と同じように見えますが、テンプレートは実際には列を尊重していませんでしたが、現在はそうしています。

        <DataGrid x:Name="_datagrid" Grid.Column="1" AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False" >
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="People">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:PersonView />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

これらの変更を行った後、私はそれが両側で更新されているのを見ました。

お役に立てば幸いです。

于 2012-12-21T01:49:26.043 に答える