我有一个带有两个只读DataGridTextColumns的数据网格和一个带有TextBox的DataGridTemplateColumn。 (我选择文本框而不仅仅是文本列的原因是因为我希望在每个数据网格行上都有一个上下文菜单,并且可以通过这种方法重命名哪个最简单。)
<DataGrid Grid.Row="0" Name="dgUsers" AutoGenerateColumns="False" ItemsSource="{Binding Path=Users, Mode=TwoWay}">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource dataGridRowContextMenu}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTemplateColumn Width="Auto" Header="Middle Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="middleName" Text="{Binding MiddleName}" Style="{StaticResource DataGridTextBox}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
数据网格的内容是双向绑定到视图模型中的对象集合。每行对应一个用户。我的viewmodel中的那些Users对象连接到数据库。我想做一些事情,当用户更改可编辑列中的文本(每行有一个文本框的列)时,数据库会相应地进行修改(经过一些数据验证等)。
我的问题是:什么是MVVM监听模板列更改并对其做出反应的好方法?
我尝试使用TextChanged事件:
<DataGridTemplateColumn Width="Auto" Header="Middle Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="middleName" Text="{Binding MiddleName}" Style="{StaticResource DataGridTextBox}"
TextChanged="middleName_TextChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
然后我的xaml.cs代码中的middleName_TextChanged()方法被调用,每个字符都被添加到文本框中...理想情况下我想要一个只在焦点离开文本框时被调用的方法(不是每个字符添加)。
我还考虑启动方法来进行输入验证,该方法是将此列绑定到的User的属性的set方法(User.MiddleName的set方法),但是这也是在每个字符插入文本框的情况下调用的
答案 0 :(得分:0)
在.xaml文件中添加 <Window.Resources>
<CollectionViewSource x:Key="ItemCollectionViewSource" CollectionViewType="ListCollectionView"/>
</Window.Resources>
这样的
DataGrid
然后在DataContext
中将ItemCollectionViewSource
添加到DataContext="{StaticResource ItemCollectionViewSource}"
这样
ItemCollectionViewSource
现在在代码后面将数据库设置为CollectionViewSource itemCollectionViewSource;
itemCollectionViewSource = (CollectionViewSource)(FindResource("ItemCollectionViewSource"));
itemCollectionViewSource.Source = YourDataBase;
,就像这样
MEMORY
{
/* Flash Size 128 KB minus the CCA area below (88 bytes) */
/* OLD: FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x0001FFA8 */
FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x0001FF88
/*
* Custom reserved memory space with size of 32 bytes
*/
CNVM (RX) : ORIGIN = 0x0001FF88, LENGTH = 32
/*
* Customer Configuration Area and Bootloader Backdoor configuration
* in flash, up to 88 bytes
*/
FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88
/* RAM Size 20KB */
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000
/* Application can use GPRAM region as RAM if cache is disabled in CCFG */
GPRAM (RWX) : ORIGIN = 0x11000000, LENGTH = 0x00002000
}
/*. Highest address of the stack. Used in startup file .*/
_estack = ORIGIN(SRAM) + LENGTH(SRAM); /* End of SRAM */
/*. Generate a link error if heap and stack don’t fit into RAM .*/
_Min_Heap_Size = 0;
_Min_Stack_Size = 0x100;
SECTIONS
{
.text :
{
_text = .;
KEEP(*(.vectors))
*(.text*)
*(.rodata*)
_etext = .;
} > FLASH = 0
.text:
{
*(.rodata*)
} > CNVM
.data :
{
_data = .;
*(vtable)
*(.data*)
_edata = .;
} > SRAM AT > FLASH
.ARM.exidx :
{
*(.ARM.exidx*)
} > FLASH
.bss :
{
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
} > SRAM
.ccfg :
{
KEEP(*(.ccfg))
} > FLASH_CCFG
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} > SRAM
.gpram :
{
} > GPRAM
}
现在,twoway绑定中的任何更改都会反映在数据库上。