我尝试创建一个DataGrid,用户可以在其中编辑数据并在之后应用oder取消更改。
此外,一个DataGridCell
有一个TemplateSelector
来帮助用户输入有效数据。 (DateTime, Boolean,...)
我的模型有一些属性。对于我的问题,有两个相关:
Model.Type
和Model.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"}"
它有用但我想处理用户的OK
或Cancel
,此代码会更改我的模型。
另一个问题: 你如何处理这样的决定。 (如何更新模型 - 命令代码)
谢谢!
答案 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>