Datagrid - 应用更改,但CellTemplate应用当前数据

时间:2015-05-07 09:54:10

标签: c# wpf xaml binding datagrid

我尝试创建一个DataGrid,用户可以在其中编辑数据并在之后应用oder取消更改。 此外,一个DataGridCell有一个TemplateSelector来帮助用户输入有效数据。 (DateTime, Boolean,...) 我的模型有一些属性。对于我的问题,有两个相关: Model.TypeModel.Value

在CodeBehind中,我的属性具有类型:

enum Type;
string Value;

当用户编辑Value时,TemplateSelector会根据Type得到正确的DataTemplate

我的XAML看起来像这样:

    <DataGrid x:Name="datagrid"                       
                      ItemsSource="{Binding Variables}"                       
                      HorizontalAlignment="Stretch"                       
                      VerticalAlignment="Stretch"                       
                      AutoGenerateColumns="False"                                  
                      IsSynchronizedWithCurrentItem="True">
                <DataGrid.Columns>
                    <DataGridComboBoxColumn Header="{StaticResource VariablesType}" 
                                            ItemsSource="{Binding Source={StaticResource VariableTypes}, Mode=OneWay}" 
                                            SelectedItemBinding="{Binding Type}" 
                                            Width="80"/>
                    <DataGridTemplateColumn Header="{StaticResource VariablesValue}" Width="2*">
                        <DataGridTemplateColumn.CellEditingTemplateSelector>
                            <TemplateSelector:TemplateSelector_Variables>
                                <!--Definitin of Templates,..-->
                            </TemplateSelector:TemplateSelector_Variables>
                        </DataGridTemplateColumn.CellEditingTemplateSelector>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Value}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
     </DataGrid>

让我们进入TemplateSelector:

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == null)
            return base.SelectTemplate(item, container);
        RaVariableType VariablenType = ((RaVariable)item).Type;
        //SelectingLogic
        //Here I would need the CURRENT type but it gives me the type of my Model
    }

我已经有了一个解决方案: 如果我使用:

SelectedItemBinding="{Binding Type, UpdateSourceTrigger="PropertyChanged"}"

它有用但我想处理用户的OKCancel,此代码会更改我的模型。

另一个问题: 你如何处理这样的决定。 (如何更新模型 - 命令代码)

谢谢!

1 个答案:

答案 0 :(得分:1)

您使用的是MVVM模式吗?您需要在View Model中处理它,只需将按钮绑定到DataGrid的SelectedItem,并在调用Command时使用它。执行此类操作的理想方法是使用命令(基本上是MVVM模式),您可以在数据对象(ViewModel)中创建命令并调用Button.Command,这样就不会出现像Button一样的任何代码。

此处显示了示例

<DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button 
                      Command="{Binding   Path=DataContext.OKCommand,       
RelativeSource= {RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}}">
                        </Button>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>

查看型号代码

 RelayCommand _okCommand;
public ICommand okCommand
{
    get
    {
        if (_ok == null)
        {
            _ok= new RelayCommand(param => this.Show());
        }
        return _ok;
    }
}

private void Show()
{
    if (Parent != null)
    {
        // Handle ok logic Here
    }
}

您是否正在使用Ninject,Unity等任何模式和实体框架来处理数据库层代码?您的viewmodel将包含属性,并且网格的列名应来自model属性。一旦属性值改变,你需要编写保存逻辑,可能使用EF或linq到sql db代码。保存逻辑将由单独的类处理,如果用户单击按钮,则视图模型应调用接口方法并执行保存。处理保存逻辑的类实例将由Unity或Ninject提供(取决于您的实现)。您的依赖项将被注入到视图模型中,您的视图模型将公开视图绑定的属性。

用于将所选项目从网格传递到模型 在ViewModel中创建一个属性以保存所选用户:public User SelectedUser {get;组; }

将datagrid视图的SelectedItem绑定到此属性:SelectedItem =“{Binding SelectedUser}”

有几种方法可以在DataGrid中选择项目。这取决于哪一种最适合您的情况

首先,最基本的是SelectedIndex,这将只选择DataGrid中该索引处的Row

<DataGrid SelectedIndex="{Binding SelectedIndex}" />

private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set { _selectedIndex = value; NotifyPropertyChanged("SelectedIndex"); }
}

SelectedIndex = 2;

SelectedItem将选择与您设置的行匹配的行

<DataGrid SelectedItem="{Binding SelectedRow}" />

private DataRow _selectedRow;
public DataRow SelectedRow
{
get { return _selectedRow; }
set { _selectedRow = value; NotifyPropertyChanged("SelectedRow");}
}

SelectedRow = items.First(x => x.whatever == something);

最常见的是SelectedValue并设置了SelectedValuePath,在这种情况下,您设置要选择的列,然后可以通过设置相应的值来选择行

<DataGrid SelectedValuePath="Size Quantity" SelectedValue="{Binding SelectionValue}" 

private string _selectedValue
public string SelectionValue 
  {
get { return _selectedValue; }
set { _selectedValue = value; NotifyPropertyChanged("SelectionValue"); }
}

SelectionValue = "Blue";

XAML示例

<Window x:Class="WpfApplication21.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="202" Width="232" Name="UI">

<Grid DataContext="{Binding ElementName=UI}">
    <DataGrid SelectedValuePath="Size Quantity"        
              SelectedValue="{Binding SelectionValue}" 
              SelectedIndex="{Binding SelectedIndex}"
              ItemsSource="{Binding SizeQuantityTable}"
              AutoGenerateColumns="True" 
              Margin="0,0,0,41" />
    <StackPanel Orientation="Horizontal" Height="37" VerticalAlignment="Bottom" >
        <Button Content="SelectedIndex" Height="26"  Width="107" Click="Button_Click_1"/>
        <Button Content="SelectedValue" Height="26"  Width="107" Click="Button_Click_2"/>
    </StackPanel>
</Grid>
</Window>