我有以下自定义datagrid列,用于将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
总是Nothing
(null
)ConverterParameter
1}}已设置。我该如何解决这个问题?
修改
在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;
}
}
}
答案 0 :(得分:0)
我可能不明白你正在尝试做什么,但这看起来像查看/编辑DatePart需要做很多工作。使用格式化程序和DataGridTextColumn会更容易吗? WPF Binding StringFormat Short Date String
答案 1 :(得分:0)
首先,请使用debug检查绑定路径是否正常。 其次,检查FromDate属性是否被触发。 第三,请使用Snoop监控此DP是否更新。
最后,我记得DataGrid有动态绑定错误,所以我不确定上面的步骤可以解决你的问题。如果不行,请告诉我。
答案 2 :(得分:0)
如果您只需要格式化值,我会推荐Darlene方法。如果你真的需要一个魔法转换器,我会建议你通过XAML中的绑定设置它(我真的不知道你为什么要在属性定义中设置它)。
您的XAML将是这样的:
<my:DataGridTimeColumn Header="From" Binding="{Binding FromDate, Converter={StaticResource myTimeConverter}} />
TimeConverter必须实现IValueConverter,并且必须在window / datagrid资源中定义实例。您还可以在该绑定中定义TwoWay。
您可以找到完整的示例here。
如果您想要合并两个或多个数据,可以使用MultiBinding。
答案 3 :(得分: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上测试并按预期工作。