在WPF

时间:2016-12-19 11:00:26

标签: c# wpf datagrid datepicker isenabled

我有一个奇怪的错误,我需要一些救援。 我有一个网格,在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会无缘无故地启用和禁用。 例: 我的所有DatePicker都已启用,我正在玩我的垂直滚动条,没问题。

我的所有DatePickers都已禁用,我正在玩我的垂直滚动条。 1 Datepicker将突然出现启用: DatePicker enabled 1

我正在使用滚动条,另一个Datepicker将启用: DatePicker enabled 2

你知道会发生什么吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

这是因为DataGrid.EnableRowVirtualization默认为true。这使得UI虚拟化成为可能,这意味着可以处置或重用滚动出视图的UI元素。因此,有时在将项目滚动到视图中时,将通过您的工厂创建新的DatePicker,当然,当调用SetChangeLockState时,这个新的DatePicker将不存在,因此不会被禁用。

快速解决方法是将DataGrid.EnableRowVirtualization设置为false,但如果您有很多行,这可能不是很有效。更好的解决方案是绑定而不是设置IsEnabled属性,例如使用RelativeSource访问窗口上的属性。

答案 1 :(得分:0)

感谢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
                    });