2

我有以下自定义数据网格列,用于将DatePart依赖属性的值作为ConverterParameter编辑元素的转换器传递:

Public Class DataGridTimeColumn
    Inherits DataGridTextColumn

    Shared ReadOnly DatePartProperty = DependencyProperty.Register("DatePart", GetType(DateTime?), GetType(DataGridTimeColumn), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, AddressOf RefreshBinding))
    Property DatePart As DateTime?
        Get
            Return GetValue(DatePartProperty)
        End Get
        Set(value As DateTime?)
            SetValue(DatePartProperty, value)
        End Set
    End Property

    Private Shared Sub RefreshBinding(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim tc As DataGridTimeColumn = d
        tc.Binding = tc.Binding
    End Sub

    Public Overrides Property Binding As BindingBase
        Get
            Return MyBase.Binding
        End Get
        Set(value As BindingBase)
            Dim b As Data.Binding = value
            With b
                .Converter = New TimeConverter
                .ConverterParameter = DatePart
            End With
            MyBase.Binding = b
        End Set
    End Property
End Class

使用以下 XAML:

<my:DataGridTimeColumn Header="From" Binding="{Binding FromDate}" DatePart="{Binding FromDate}" />
<my:DataGridTimeColumn Header="Until" Binding="{Binding TillDate}" DatePart="{Binding TillDate}" />

但是RefreshBinding永远不会被调用(我已经设置了一个断点并且它从未被触发),因此在设置时DatePart总是NothingnullConverterParameter。我怎样才能解决这个问题?

编辑

在 C# 中:

public class DataGridTimeColumn : DataGridTextColumn
{
    static readonly DependencyProperty DatePartProperty = DependencyProperty.Register(
        "DatePart", typeof(DateTime?), typeof(DataGridTimeColumn),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, RefreshBinding)
    );

    public DateTime? DatePart
    {
        get { return (DateTime?)GetValue(DatePartProperty); }
        set { SetValue(DatePartProperty, value); }
    }

    private static void RefreshBinding(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    {
        var tc = (DataGridTimeColumn)d;
        tc.Binding = tc.Binding;
    }

    public override System.Windows.Data.BindingBase Binding
    {
        get { return base.Binding; }
        set
        { 
            var b = (Binding)value;
            b.Converter = new TimeConverter();
            b.ConverterParameter = DatePart;
            base.Binding = b;
        }
    }
}
4

4 回答 4

0

如果您只需要格式化值,我会推荐 Darlene 方法。如果你真的需要一个转换器来获得一些魔法,我建议通过你在 XAML 中的绑定来设置它(我真的不知道你为什么要在属性定义中设置它)。

您的 XAML 将是这样的:

 <my:DataGridTimeColumn Header="From" Binding="{Binding FromDate, Converter={StaticResource myTimeConverter}} />

TimeConverter 必须实现 IValueConverter 并且必须在您的窗口/数据网格资源中定义一个实例。您还可以在该绑定中定义 TwoWay。

您可以在此处找到完整示例。

如果您想组合两条或更多条数据,您可以使用MultiBinding

于 2013-06-15T05:08:03.950 回答
0

我可能不明白您到底想做什么,但这似乎需要大量工作来查看/编辑 DatePart。使用格式化程序和 DataGridTextColumn 会更容易吗?WPF 绑定 StringFormat 短日期字符串

于 2013-06-11T19:29:22.437 回答
0

试图从评论中了解您想要实现的目标,如果我做对了,您可以只使用视图模型和一个带有小解决方法的转换器来做到这一点:

在您的转换器 ConvertBack 方法中,您可以尝试确定用户输入的值是否只有时间部分,如果是,请将日期设置为不会使用的值(例如 DateTime.MinValue):

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    var convertedDateTime = DateTime.Parse(value.ToString());
    var hasOnlyTime = value.ToString().Trim().Length <= 5; // This should be replaced with something more consistent

    if (hasOnlyTime)
        return new DateTime(DateTime.MinValue.Year, DateTime.MinValue.Month, DateTime.MinValue.Day, convertedDateTime.Hour, convertedDateTime.Minute, convertedDateTime.Second);

    return convertedDateTime;
}

然后在日期的对象设置器中,您可以检查并使用所需的值,如果日期部分是 DateTime.MinValue 将其更改回前一个,如果不是保持原样:

 private DateTime _fromDate;
 public DateTime FromDate
 {
    get { return _fromDate; }
    set 
    {
        if (value.Date != DateTime.MinValue)
            _fromDate = value;
        else
            _fromDate = new DateTime(_fromDate.Year, _fromDate.Month, _fromDate.Day, value.Hour, value.Minute, value.Second);

        OnPropertyChanged("FromDate");
    }
 }

在 .NET 4.5 上测试并按预期工作。

于 2013-06-17T09:05:28.750 回答
0

首先,请使用调试检查您的绑定路径是否正常。其次,检查您的 FromDate 属性是否被触发。三、请使用Snoop监控该DP是否更新。

最后,我记得 DataGrid 有动态绑定错误,所以我不确定上述步骤能否解决您的问题。如果不行,请告诉我。

于 2013-06-13T03:48:10.770 回答