2017-09-28 26 views
0

WPFのDataGridコントロールに基づいてカスタムDataGridを作成しようとしています。私は "ItemsDataSource"と呼ばれる別のプロパティを作成し、それを使って自分のViewModelsからコレクションをバインドします。このプロパティでValueChangedイベントが発生すると、ItemsSourceの値がItemsDataSourceの値に設定されます。WPF - ItemsSourceプロパティにバインドしていないときに、新しいアイテム行がDataGridに表示されない

グリッドが読み取り専用モードで、CanUserAddRowsプロパティをTrueに設定すると、ItemsDataSourceが空の場合、DataGridに新しい行が追加されることはありません。しかし、ItemsDataSourceの代わりにItemsSourceにバインディングを戻した場合、DataGridは新しい行を表示します。ここで

は私のカスタムグリッドのための部分的なコードです:

public partial class NewDataGrid : DataGrid 
{ 
    public NewDataGrid() 
    { 
     InitializeComponent(); 

     var dpd = DependencyPropertyDescriptor.FromProperty(ItemsDataSourceProperty, typeof(NewDataGrid)); 

     dpd?.AddValueChanged(this, (s, a) => 
     { 
      ItemsSource = ItemsDataSource.Cast<object>().ToList(); 
     }); 
    } 

    public IList ItemsDataSource 
    { 
     get { return (IList)GetValue(ItemsDataSourceProperty); } 
     set { SetValue(ItemsDataSourceProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsDataSourceProperty = 
       DependencyProperty.Register("ItemsDataSource", typeof(IList), typeof(NewDataGrid), new PropertyMetadata(null)); 
} 

そして、ここでは、私はXAMLでバインディングをやっている方法です。ここで

<WPF:NewDataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
     ItemsDataSource="{Binding Path=DataContext.DataWrapperList, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}" 
     SelectedValue="{Binding Path=DataContext.SelectedDataWrapper, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}" 
     AutoGenerateColumns="False" 
     Validation.ErrorTemplate="{x:Null}" 
     Margin="0" 
     VerticalScrollBarVisibility="Auto" 
     SelectionMode="Single" 
     CanUserAddRows="True" 
     CanUserDeleteRows="True" 
     IsReadOnly="False"> 

    <DataGrid.Columns> 
     <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*" SortMemberPath="Name" /> 
     <DataGridTextColumn Header="Quantity" Binding="{Binding Path=Quantity}" Width="*" SortMemberPath="Quantity" /> 
</WPF:PAENewDataGrid> 

はDataListWrapperプロパティがで宣言されている方法です私のDataContext:ここ

public ObservableCollection<DataWrapper> DataWrapperList; 

は私のDataWrapperクラスです:

public class DataWrapper : BaseWrapper 
{ 
    private DataWrapperDTO _data; 

    public DataWrapper() 
    { 
     _data = new DataWrapperDTO(); 
    } 

    public DataWrapper(DataWrapperDTO data) 
    { 
     _data = data; 
    } 

    public string Name 
    { 
     get { return _data.Name; } 
     set 
     { 
      _data.Name = value; 
      RaisePropertyChanged(nameof(Name)); 
     } 
    } 

    public int Quantity 
    { 
     get { return _data.Quantity; } 
     set 
     { 
      _data.Quantity = value; 
      RaisePropertyChanged(nameof(Quantity)); 
     } 
    } 
} 

CanUserAddRowsプロパティがTrueに設定されているときに、常にこの新しい行を表示するようにDataGridを強制する方法は誰にも分かりますか?

+0

あなたは 'DataWrapperList'プロパティを提供してください。 'ItemsSource = ItemsDataSource.Cast ().ToList();'の '().ToList()'を削除することもチェックします。私は現在それを確認する対PCの前にはないが、私は 'ItemsSource'はリスト内の1つの項目を持つ' List 'であると思います。 –

+0

@MartinBackasch提案した変更を加えましたが、まだ動作していません:( – Juan

+0

ItemsSourceに直接バインドするのはどうですか? – ncfuncion

答えて

0

のItemsSourceに新しいアイテムが追加されるたびに交換しないで試してみてください。この問題に少し苦戦した後

public NewDataGrid() 
    { 
     InitializeComponent(); 

     ItemsSource = new ObservableCollection<object>(); 

     var dpd = DependencyPropertyDescriptor.FromProperty(ItemsDataSourceProperty, typeof(NewDataGrid)); 


     dpd?.AddValueChanged(this, (s, a) => 
     { 
      ItemsSource.Clear(); 
      ItemsSource.Add(ItemsDataSource.Cast<object>().ToList()); 
     }); 
    } 
0

を、私が解決策を見つけたようです。 DependencyPropertyをPropertyChangedCallbackに登録し、このコールバック内の新しい値にItemsSourceを割り当てると、新しい値を追加するためにグリッドに空白行が追加されます。ヘルプみんなのため

public partial class NewDataGrid : DataGrid 
{ 
    public NewDataGrid() 
    { 
     InitializeComponent(); 
     //Removed the DependencyPropertyDescriptor 
    } 

    public IList ItemsDataSource 
    { 
     get { return (IList)GetValue(ItemsDataSourceProperty); } 
     set { SetValue(ItemsDataSourceProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsDataSourceProperty = 
      DependencyProperty.Register("ItemsDataSource", typeof(IList), typeof(NewDataGrid), new PropertyMetadata(null, ItemsDataSourceChanged)); 

    private static void ItemsDataSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     var grid = sender as NewDataGrid; 
     if (grid == null) return; 

     grid.ItemsSource = ((IList)args.NewValue).Cast<object>().ToList(); 
    } 
} 

ありがとう:

NewDataGridクラスのコードは次のようになります!

関連する問題