2016-06-08 11 views
4

我有我用来填充数据网格的用户控件。如何让数据网格看到控件中的编辑?

我希望用户能够通过编辑底部的空行来添加项目。 (这就是我使用datagrid而不是项目控件的原因)但是,datagrid没有意识到最后的项目被编辑,除非用户单击控件的背景。我希望在用户对控件公开的属性进行更改时添加新项目。

XAML控制的:

<UserControl x:Class="ControlTest.MyControl" 
     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" 
     xmlns:local="clr-namespace:ControlTest" 
     mc:Ignorable="d" 
     d:DesignHeight="50" d:DesignWidth="300" 
     DataContext="{Binding Path=., Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
     > 
<StackPanel Orientation="Vertical"> 
     <TextBox Text="{Binding Path=p1, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
      Width="300" 
      Height="30" 
      VerticalAlignment="Center"/> 
    <ComboBox ItemsSource="{Binding Path=DropDownValues, 
       RelativeSource={RelativeSource Mode=FindAncestor, 
       AncestorType=local:MyControl}}" 
       SelectedItem="{Binding Path=p2, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
       Height="30"/> 
    </StackPanel> 
</UserControl> 

CS:

public partial class MyControl : UserControl 
{ 
    private static readonly DependencyProperty DropDownValuesProperty = 
     DependencyProperty.Register(
     "DropDownValues", 
     typeof(List<String>), 
     typeof(MyControl), 
     new FrameworkPropertyMetadata(new List<String>() 
     )); 
    public List<String> DropDownValues 
    { 
     get 
     { 
      return (List<String>)GetValue(DropDownValuesProperty); 
     } 
     set 
     { 
      SetValue(DropDownValuesProperty, value); 
     } 
    } 

    public MyControl() 
    { 
     InitializeComponent(); 
    }   
} 

DataGrid的XAML

<DataGrid 
     AutoGenerateColumns="False" 
     ItemsSource="{Binding objs, Mode=TwoWay}" 
     HeadersVisibility="None" 
     Margin="0,0,0.4,0" 
     CanUserAddRows="True" 
     > 
     <DataGrid.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </DataGrid.ItemsPanel> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="300"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate DataType="local:Measure"> 
         <local:MyControl 
          DataContext="{Binding ., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          DropDownValues= 
         "{Binding DataContext.list, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
          Width="300" 
         /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

我可以做这项工作,和/或是否有更好的方法来做到这个?

+0

你是什么意思:datagrid没有意识到最后一项编辑,除非用户单击控件的背景。我的意思是什么是默认行为? – Vishal

+0

@Vishal没有控制权的缺省行为是,一旦新对象失去焦点,就会添加新对象。这有点类似于我在观察控件时观察到的情况,但datagrid并不理解单元格是我编辑的控件中的控件之一,因此不会添加新项目,除非点击背景控制。 – Taemyr

+0

你怎么知道Datagrid不知道最后一个项目已被编辑?你是直接添加到“Items”还是添加到'objs'? – M312V

回答

1

问题是UI未被通知objs集合的更改通知?我会做的是尝试设置任何包含objs的视图模型,以使objs成为可观察的集合。我还要确保objs是可观察的实现INotifyPropertyChanged集合,并且属性p1和p2在设置时都会触发OnPorpertyChanged。

public ObservableCollection<YourObject> objs 

public class YourObject : INotifyPropertyChanged 
{ 
    protected void OnPropertyChanged(string Name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(Name)); 
     } 
    } 

    private string _p1; 
    public string p1 
    { 
     get { return _p1; } 
     set 
     { 
      if (_p1 != value) 
      { 
       _p1 = value; 
       OnPropertyChanged("p1"); 
      } 
     } 
    } 
    private string _p2; 
    public string p2 
    { 
     get { return _p2; } 
     set 
     { 
      if (_p2 != value) 
      { 
       _p2 = value; 
       OnPropertyChanged("p2"); 
      } 
     } 
    } 
} 
+0

问题是,当我在控件中的项目中进行更改时,新项目未添加到集合中。 - 如果我从数据网格的外部对集合进行了更改升级,但是要使数据网格向集合添加项目,我必须单击控件的背景 - 我希望在创建新项目时添加开始编辑控件中的项目。 – Taemyr

+0

集合已经是实现INotifyPropertyChanged的类的可观察集合。 – Taemyr

+0

尝试InvalidateArrange和/或InvalidateMeasure。 – M312V

2

我想建议你这样做,以不同的方式:

设置CanUserAddRows=false您的DataGrid,然后手动行添加到ObservableCollection<Something>到您的DataGrid是势必。

OR

如果你仍然有兴趣在你采取的办法:

在您的XAML文件:

<DataGrid x:Name="myDataGrid" CellEditEnding="DataGrid_CellEditEnding" .....> 
    <!--Some Code--> 
</DataGrid> 

然后在代码隐藏:

private void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    myDataGrid.CommitEdit(); 
} 

如果你什么都不懂, ñ随时问。

更新

如果您遵循相同的方法:

在你的DataGrid的开始编辑的事件,你可以尝试:

private void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) 
{ 
    if ((selectedRow as DataGridRow).Item.ToString() != "{NewItemPlaceholder}") 
    { 
     //Here you can add the code to add new item. I don't know how but you should figure out a way 
    } 
} 

注:上面提到的代码是不测试。

我也建议你:

不使用DataGrid。而是使用ListBox。因为,你正试图添加一些数据。在这个时候,你永远不需要排序,搜索和列重新排序的功能。在这种情况下,ListBox是有用的,因为它比数据网格轻量级控制。我在这里有一个示例:https://drive.google.com/open?id=0B5WyqSALui0bTXFGZWxQUWVRdkU

+0

在CellEditEnding上设置CommitEdit并不会导致在控件中的字段中进行更改时创建新项目。当我双击控件的背景时,它确实会导致一个stackoverflow异常。 – Taemyr

+0

有没有办法手动添加行而不使控件知道集合? – Taemyr

+0

@Taemyr请看看我更新的答案。 – Vishal

相关问题