WPF DataGrid在编辑时

时间:2019-06-25 10:29:09

标签: c# wpf xaml datagrid

我有一个非常简单的(部分)数据绑定ViewModel,它公开了一个Nullable属性,该属性随后在DataGrid中呈现:

public class MyViewModel : ViewModelBase
{
   private DateTime? _date;
   public DateTime? Date {
     get => _date;
     set => Set(ref _date, value);
   }
}

<DataGrid ItemsSource="{Binding MyViewModels}">
   <DataGrid.Columns>
      <DataGridTextColumn Header="Date" Binding="{Binding Date}"/>
   </DataGrid.Columns>
</DataGrid>

一切正常,显示具有值的日期,null值的单元格完全空白。
但是,在进入单元格编辑模式时,如何用null预填充绑定的DateTime.Now值?奖励点:在单元格编辑被中止的情况下,DateTime.Now返回到null


尝试2 (基于评论),使用DataGridTemplateColumn并将TextBlock不包含TargetNullValue的内容替换为TextBox,包含一个内容的情况,不是有效的绑定:

  

TargetNullValue'6/25/2019 0:00:00'(类型'DateTime')不能为   转换为在“文本”中使用

<DataGridTemplateColumn SortMemberPath="Date" Header="Date">
   <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Date}"/>
      </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellEditingTemplate>
      <DataTemplate>
         <TextBox Text="{Binding Date, TargetNullValue={x:Static sys:DateTime.Today}}"/>
      </DataTemplate>                            
   </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

2 个答案:

答案 0 :(得分:3)

如果绑定到不可见的TargetNullValue的{​​{1}}属性,则可以使用SelectedDate属性:

DatePicker

另一种选择是实现将<DataGridTemplateColumn SortMemberPath="Date" Header="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <StackPanel> <DatePicker x:Name="dp" SelectedDate="{Binding Date, TargetNullValue={x:Static sys:DateTime.Today}}" Visibility="Collapsed" /> <TextBox Text="{Binding Text, ElementName=dp}" /> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 转换为DateTime.Today的{​​{3}}。

  

感谢您的回答,它肯定简单得多,并且允许使用非静态值。但是,除非用户将其更改为其他日期然后返回...,否则无法接受预先填写的DateTime.Today。

如果要保留该值,则应显式设置source属性。您可以通过处理string事件来做到这一点。像这样:

CellEditEnding

答案 1 :(得分:1)

您可以使用MultiDataTrigger并编写条件(如果日期等于null且文本框已聚焦),我们可以将值设置为DateTime.now

DataGridTemplateColumn

 <DataGrid Name="drg" AutoGenerateColumns="False"  CanUserAddRows="False" >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Date" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox  BorderThickness="0" >
                                <TextBox.Style>
                                    <Style TargetType="TextBox">
                                        <Style.Resources>
                                            <Converter:DateTimeNullConverter x:Key="Time"/>
                                        </Style.Resources>
                                        <Setter Property="Text" Value="{Binding Date}"></Setter>

                                        <Style.Triggers>
                                            <MultiDataTrigger>
                                                <MultiDataTrigger.Conditions>
                                                    <Condition Binding="{Binding Date}" Value="{x:Null}" />
                                                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsKeyboardFocused}" Value="True" />
                                                </MultiDataTrigger.Conditions>
                                                <Setter Property="Text" Value="{Binding Date,Converter={StaticResource Time}}"></Setter>
                                            </MultiDataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBox.Style>

                            </TextBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

转换器

DateTimeNullConverter类:IValueConverter     {

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return DateTime.Now;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}