如何使数据网格看到控件中的编辑?

时间:2016-06-08 11:43:31

标签: c# wpf xaml 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>

我可以做这项工作,和/或有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我想建议你采取不同的方式:

在DataGrid上设置CanUserAddRows=false,然后手动将行添加到DataGrid绑定到的ObservableCollection<Something>

如果您仍然对您遵循的方法感兴趣:

在你的xaml文件中:

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

然后在Code-Behind:

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很有用,因为它比datagrid轻量级控制。我在这里有一个示例:https://drive.google.com/open?id=0B5WyqSALui0bTXFGZWxQUWVRdkU

答案 1 :(得分:1)

是否没有通知用户界面对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");
            }
        }
    }
}