在 WPF 中使用垂直滚动条时启用日期选择器列
Datepicker column enabling itself when playing with vertical scrollbar in WPF
我有一个奇怪的错误,我需要一些救援。
我在 WPF 中有一个包含多个类型的多个列的网格。
这些列中的一个或多个是我通过 FrameElementFactory 创建的 DatePickers :
FrameworkElementFactory dateFactory = new FrameworkElementFactory(typeof(DatePicker));
...
column = new DataGridTemplateColumn { CellTemplate = new DataTemplate
{ VisualTree = dateFactory } };
this._mainDatagrid.Columns.Add(column);
我已经使用一种方法在我的一个变量的特定状态下禁用我的网格的 DatePickers:
private IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
//return the Datagrid Rows
}
public void SetChangeLockState(bool isUnlocked)
{
IEnumerable<DataGridRow> _rows = this.GetDataGridRows(this._mainDatagrid);
foreach (DataGridColumn _column in this._mainDatagrid.Columns)
{
if (_column.GetType() != typeof(DataGridTemplateColumn)) continue;
foreach (DataGridRow _row in _rows)
{
FrameworkElement frameworkElement = _column.GetCellContent(_row);
if (frameworkElement != null) frameworkElement.IsEnabled = !isUnlocked;
}
}
}
问题是,当我玩我的网格电梯时,日期选择器无缘无故地不断启用和禁用。
例子:
我所有的 DatePicker 都启用了,我正在玩我的垂直滚动条,没问题。
我所有的 DatePickers 都被禁用了,我正在玩我的垂直滚动条。
1 Datepicker会突然出现enable:
DatePicker enabled 1
我一直在玩滚动条,另一个日期选择器将启用:
DatePicker enabled 2
你知道会发生什么吗?
感谢您的帮助。
这是因为 DataGrid.EnableRowVirtualization
默认为 true。这启用了 UI 虚拟化,这意味着 UI 滚动到视图之外的元素可以被处理或重新使用。因此,有时当将项目滚动回视图时,将通过您的工厂创建一个新的 DatePicker,当然,调用 SetChangeLockState
时这个新的 DatePicker 将不存在,因此不会被禁用。
一个快速修复方法是将 DataGrid.EnableRowVirtualization
设置为 false,但如果您有很多行,这可能不会非常高效。更好的解决方案是绑定而不是设置 IsEnabled
属性,例如使用 RelativeSource 到 Window 上的 属性。
感谢 Ben,这是代码:
dateFactory.SetBinding(
//My IsEnabled property I wanted to change
IsEnabledProperty,
new Binding("IsLockedDatagrid")
{
//Datagridwidget is the datagrid I am using where I can found the IsLockedDatagrid boolean variable (in my xaml)
RelativeSource =
new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridWidget), 1),
Mode = BindingMode.OneWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
我有一个奇怪的错误,我需要一些救援。 我在 WPF 中有一个包含多个类型的多个列的网格。 这些列中的一个或多个是我通过 FrameElementFactory 创建的 DatePickers :
FrameworkElementFactory dateFactory = new FrameworkElementFactory(typeof(DatePicker));
...
column = new DataGridTemplateColumn { CellTemplate = new DataTemplate
{ VisualTree = dateFactory } };
this._mainDatagrid.Columns.Add(column);
我已经使用一种方法在我的一个变量的特定状态下禁用我的网格的 DatePickers:
private IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
//return the Datagrid Rows
}
public void SetChangeLockState(bool isUnlocked)
{
IEnumerable<DataGridRow> _rows = this.GetDataGridRows(this._mainDatagrid);
foreach (DataGridColumn _column in this._mainDatagrid.Columns)
{
if (_column.GetType() != typeof(DataGridTemplateColumn)) continue;
foreach (DataGridRow _row in _rows)
{
FrameworkElement frameworkElement = _column.GetCellContent(_row);
if (frameworkElement != null) frameworkElement.IsEnabled = !isUnlocked;
}
}
}
问题是,当我玩我的网格电梯时,日期选择器无缘无故地不断启用和禁用。 例子: 我所有的 DatePicker 都启用了,我正在玩我的垂直滚动条,没问题。
我所有的 DatePickers 都被禁用了,我正在玩我的垂直滚动条。 1 Datepicker会突然出现enable: DatePicker enabled 1
我一直在玩滚动条,另一个日期选择器将启用: DatePicker enabled 2
你知道会发生什么吗?
感谢您的帮助。
这是因为 DataGrid.EnableRowVirtualization
默认为 true。这启用了 UI 虚拟化,这意味着 UI 滚动到视图之外的元素可以被处理或重新使用。因此,有时当将项目滚动回视图时,将通过您的工厂创建一个新的 DatePicker,当然,调用 SetChangeLockState
时这个新的 DatePicker 将不存在,因此不会被禁用。
一个快速修复方法是将 DataGrid.EnableRowVirtualization
设置为 false,但如果您有很多行,这可能不会非常高效。更好的解决方案是绑定而不是设置 IsEnabled
属性,例如使用 RelativeSource 到 Window 上的 属性。
感谢 Ben,这是代码:
dateFactory.SetBinding(
//My IsEnabled property I wanted to change
IsEnabledProperty,
new Binding("IsLockedDatagrid")
{
//Datagridwidget is the datagrid I am using where I can found the IsLockedDatagrid boolean variable (in my xaml)
RelativeSource =
new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridWidget), 1),
Mode = BindingMode.OneWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});