0

私のプログラムにはDataGrid、UserControl の一部である があります。このグリッドのセルの値を変更して、データ モデルに保存できるようにしたいと考えています。これは、標準のデータ バインドtextBoxが wpf でどのように機能するかに似ています。

はesDataGridで構成されています。TextBoxセルの値を変更することはできますが、ページから移動すると消えます。

ユーザー コントロール XAML:

<DataGrid ItemsSource="{Binding DataModel.Collection}" ... >
              <DataGrid.Columns>
                   <DataGridTemplateColumn IsReadOnly="True">
                         <DataGridTemplateColumn.CellTemplate>
                               <DataTemplate>
                                    <TextBox Text="{Binding rowNum}" />
                                </DataTemplate>
                         </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                          .......
                    </DataGrid>

データ・モデル:

public class Data_Model : PropertyChangedBase
{
    private string one = "One";
    private string two = "Two";
    private string three = "Three";
    private string four = "Four";
    private string a = "A";
    private string b = "B";
    private string c = "C";
    private string d = "D";

    private ObservableCollection<Class> _Collection; 

    public Data_Model()
    {
        Collection = new ObservableCollection<Class>();
        Collection.Add(new Class() { rowNum = 0, input = one, output = a });
        Collection.Add(new Class() { rowNum = 1, input = two, output = b});
        Collection.Add(new Class() { rowNum = 2, input = three, output = c});
        Collection.Add(new Class() { rowNum = 3, input = four, output = d});

    }

    public ObservableCollection<Class> Collection {...}
}

public class Class //Class for DataGrid values
{
    public int rowNum { set; get; }
    public string input { set; get; }
    public string output { set; get; }
}

ユーザーが入力した値を通常のようにこれらのセルに格納するにはどうすればよいですか (stringのテキストとして機能するプロパティを記述することによってtextBox) ?

4

2 に答える 2

1

data_model の各プロパティに対して NotifyPropertyChanged("PropertyName") を呼び出し、バインディングを設定するだけでよいと思いますMode=twoway

private int rowNum;

public int RowNum
{
    get { return rowNum; }
    set
    {
        rowNum = value;
        RaisePropertyChanged("RowNum");
    }
}

また、次のように templatecolumn の代わりに DataGridTextColumn を試すことができます

<Window.Resources>
    <XmlDataProvider x:Key="customerdata" Source="customers.xml" XPath="Data" />
</Window.Resources>
<Grid>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource customerdata}, XPath=Customer}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="First Name" Binding="{Binding XPath=@FirstName}" FontFamily="Arial" FontStyle="Italic" />
            <DataGridTextColumn Header="Last Name" Binding="{Binding XPath=@LastName}" FontFamily="Arial" FontWeight="Bold" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
于 2013-10-22T20:57:17.040 に答える
1

セルが編集可能な場合、WPF DataGrid はトランザクション スコープを使用します。これは、View Model が現在リッスンしていない「コミット」および「キャンセル」コマンドを DataGrid が送信していることを意味します。そのため、変更が持続していないように見えます (つまり、これらのインスタンスの「コミット」を無視しています)。

「コミット」および「キャンセル」メッセージをキャプチャするには、バインドされたクラスで IEditableObject を実装し、必要なロジックをコーディングする必要があります。IEditableObject のドキュメントはこちら: http://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject.aspx

ROWで「キャンセル」が行われると、グリッドはその行のCELLSで行われたすべてのコミットをロールバックします。WPF DataGrid のこの側面は、多くの人々を悩ませてきたので、「落とし穴」の地位を獲得しました...

IEditableObject に慣れていない場合は、適切な説明とコード サンプルが記載されているこの MSDN の記事を参照してください。DataGrid には、IEditableObject インターフェイスを介したトランザクション編集の機能が組み込まれています。セルの編集を開始すると、DataGrid はセル編集モードと行編集モードになります。これが意味することは、行をキャンセル/コミットするだけでなく、セルをキャンセル/コミットできるということです。たとえば、セル 0 を編集し、Tab キーを押して次のセルに移動します。タブを押すと、セル 0 がコミットされます。セル 1 に入力し始めて、操作をキャンセルしたいことに気付きました。「Esc」を押すと、セル 1 が元に戻ります。操作全体をキャンセルしたいので、もう一度「Esc」を押すと、セル 0 が元の値に戻ります。

ソース: http://blogs.msdn.com/b/vinsibal/archive/2009/04/07/5-random-gotchas-with-the-wpf-datagrid.aspx

したがって、「クラス」クラスに IEditableObject を実装すると、探している動作が得られるようになります。これは、完了したら次のように表示されるはずです...

public class Class : INotifyPropertyChanged, IEditableObject
{
    private int _rowNum;
    public int RowNum
    {
        [DebuggerStepThrough]
        get { return _rowNum; }
        [DebuggerStepThrough]
        set
        {
            if (value != _rowNum)
            {
                _rowNum = value;
                OnPropertyChanged("RowNum");
            }
        }
    }
    private string _input;
    public string Input
    {
        [DebuggerStepThrough]
        get { return _input; }
        [DebuggerStepThrough]
        set
        {
            if (value != _input)
            {
                _input = value;
                OnPropertyChanged("Input");
            }
        }
    }
    private string _output;
    public string Output
    {
        [DebuggerStepThrough]
        get { return _output; }
        [DebuggerStepThrough]
        set
        {
            if (value != _output)
            {
                _output = value;
                OnPropertyChanged("Output");
            }
        }
    }
    #region INotifyPropertyChanged Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
    #region IEditableObject Implementationi
    public void BeginEdit()
    {
        // your implementation goes here
    }
    public void CancelEdit()
    {
        // your implementation goes here
    }
    public void EndEdit()
    {
        // your implementation goes here
    }
    #endregion
}
于 2013-10-22T20:41:49.240 に答える