【问题标题】:IMultiValue Converter IssueIMul​​tiValue 转换器问题
【发布时间】:2018-06-08 21:00:56
【问题描述】:

DataGrid 的 ItemsSource 绑定到 ObservableCollection。其中两个 DataGridColumns 绑定到集合中的 DateTime 属性,而第三列用于使用 IMultiValue 转换器显示它们之间的日期差异。我试图理解和解决的行为可以在场景 2 中找到。

场景 1:没有问题

视图已打开且 DataGrid 已包含记录,因为集合不为空。如果将新对象添加到集合中,它将显示在 DataGrid 中,最后一列正确显示日期差值。

场景 2:有问题

视图已打开,但 DataGrid 不包含任何记录,因为集合为空。如果将新对象添加到集合中,它将显示在 DataGrid 中,但最后一列(包含转换器)为空。但是,如果视图随后关闭并重新打开,则日期差异会在 DataGrid 中正确显示。

我希望在第一次将对象添加到空集合时在 DataGrid 列中显示日期差异值。我错过了什么?

对象类

public class Evaluation
{

    public int ID { get; set; }
    public DateTime BirthDate { get; set; }
    public DateTime TestDate { get; set; }
}

视图模型

public class EvaluationViewModel : ViewModelBase  
{

private ObservableCollection<Evaluation> evaluations;

public class EvaluationViewModel()
{
    evaluations = Utility.Convert<Evaluation>(db.evaluationRepository.GetAllById(Subject.ID));
    TestView = (CollectionView)new CollectionViewSource { Source = Evaluations }.View;
    TestView.SortDescriptions.Add(new SortDescription("TestDate", ListSortDirection.Ascending));
}



    public ObservableCollection<Evaluation> Evaluations
    {
        get { return evaluations; }

    }

    public CollectionView TestView { get; set; }

}

查看

public class Evaluation
{
    public int ID { get; set; }
    public DateTime BirthDate { get; set; }
    public DateTime TestDate { get; set; }
}


<Window.Resources>
    <converters:DateDiffMonthMultiConverter x:Key="DateConverter"/>
</Window.Resources>

    <DataGrid ItemsSource="{Binding TestView}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=ID}" Visibility="Hidden"/>
            <DataGridTextColumn Header="Birth Date" Binding="{Binding BirthDate}"/>
            <DataGridTextColumn Header="Test Date" Binding="{Binding TestDate}"/>
            <DataGridTemplateColumn Header="Age When Tested">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource DateConverter}">
                                    <Binding Path="BirthDate"/>
                                    <Binding Path="TestDate"/>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

转换器

public class DateDiffMonthMultiConverter : IMultiValueConverter
{        
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {            
        string result = string.Empty;
        if(values[0] is DateTime && values[1] is DateTime)
        {
            DateTime start = (DateTime)values[1];
            DateTime end = (DateTime)values[0];
            TimeSpan ts = start - end;
            double avgDaysPerMonth = 30.4;
            double months = (double)ts.Days / avgDaysPerMonth;
            string suffix = months > 1 ? "mths" : "mth";
            result = string.Format("{0} {1}", months.ToString("0.0"), suffix);                 
        }           
        return result;
    }

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

【问题讨论】:

    标签: c# wpf mvvm datagrid


    【解决方案1】:

    我尝试了您的代码(2 秒后将项目添加到 ObservableCollection),它对我有用。这是我的代码:

    MainWindow.xaml.cs

    public MainWindow()
    {
        InitializeComponent();
        DataContext = new EvaluationViewModel();
        Loaded += MainWindow_Loaded;
    
    }
    
    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() => Thread.Sleep(2000))
        .ContinueWith((t) =>
        {
            (DataContext as EvaluationViewModel).Evaluations.Add(
          new Evaluation() { ID = 2, BirthDate = DateTime.Now.AddYears(-22), TestDate = DateTime.Now });
        }, TaskScheduler.FromCurrentSynchronizationContext());
    }
    

    视图模型

    public EvaluationViewModel()
    {
        Evaluations = new ObservableCollection<Evaluation>();
        TestView = (CollectionView)new CollectionViewSource { Source = Evaluations }.View;
        TestView.SortDescriptions.Add(new SortDescription("TestDate", ListSortDirection.Ascending));
    }
    
    public ObservableCollection<Evaluation> Evaluations { get; }
    public CollectionView TestView { get; set; }
    

    【讨论】:

    • 好的,我的代码中肯定有一些我看不到的错误,我现在正在查看。
    【解决方案2】:

    事实证明转换器不是问题,而是转换器使用的值之一是 DependencyProperty(直到现在我才意识到这一点很糟糕)并且引发​​了 DependencyProperty.UnsetValue 错误。在向集合中添加新实体时,我能够通过使用 CreateNew() 方法解决此问题,因此在将对象加载到 DataGrid 时导航属性是已知的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 2013-07-05
      相关资源
      最近更新 更多