WPF DataGrid - 禁用时保留选择 [英] WPF DataGrid - Retain selection when disabling

查看:634
本文介绍了WPF DataGrid - 禁用时保留选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力争取一段时间。我的应用程序中有一个Master / Details布局,并且像许多其他人一样遇到DataGrid在禁用它时失去选择的问题。 Essencialy,从列表中选择一个元素以填充一系列的字段后,用户按编辑,禁用DataGrid并启用所有窗体的字段。保存数据后按保存按钮可以恢复这些动作。



我在Windows 7中使用.Net Framework 4中的VS 2010进行开发。





1)根据这篇文章,我试图在2009年6月的WPF工具包版本中使用DataGrid,但我也有同样的反应。

2)基于这个WPF CodePlex错误报告,我试图创建一个基于DataGrid的自定义控件,并覆盖OnIsEnabledChanged调用要删除对UnselectAllCells的调用,但没有代码示例,我甚至不能一次启动它。我试过:

  public class FormMainDataGrid:DataGrid 
{
static FormMainDataGrid()
{
IsEnabledProperty.OverrideMetadata(typeof(FormMainDataGrid)),新的FrameworkPropertyMetadata(新的PropertyChangedCallback(OnIsEnabledChanged)));
}

public FormMainDataGrid():base(){}

private static void OnIsEnabledChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(CanUserAddRowsProperty);
d.CoerceValue(CanUserDeleteRowsProperty);

//这是添加在新版本!!!
/ *
if(!(bool)(e.NewValue))
{
((DataGrid)d).UnselectAllCells();
}
* /

//许多命令使用IsEnabled来确定是否启用
CommandManager.InvalidateRequerySuggested();
}
}

但是,这仍然会立即取消选择当前选择的行我禁用了DataGrid。我试图插入最后的评论(在Codeplex bug报告中),如下所示:

  public class FormMainDataGrid:DataGrid 
{
static FormMainDataGrid()
{

}

public static void OverrideStuff()
{
IsEnabledProperty.OverrideMetadata (typeof(FormMainDataGrid),新的FrameworkPropertyMetadata(新的PropertyChangedCallback(OnIsEnabledChanged)));
}

public FormMainDataGrid():base(){}

private static void OnIsEnabledChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(CanUserAddRowsProperty);
d.CoerceValue(CanUserDeleteRowsProperty);

//这是添加在新版本!!!
/ *
if(!(bool)(e.NewValue))
{
((DataGrid)d).UnselectAllCells();
}
* /

//许多命令使用IsEnabled来确定是否启用
CommandManager.InvalidateRequerySuggested();
}
}

public partial class App:Application
{
protected override void OnStartup(StartupEventArgs e)
{
FormMainDataGrid.OverrideStuff();
base.OnStartup(e);
}
}

但是,甚至没有启动修改版本的方法。



首先,我是正确的方法吗?考虑到Deselection是由这种方法引起的,我可以完全替换内部调用OnIsEnabledChanged为我自己的方法吗?
有另一种方法可以解决这个问题吗?
或者更具体地说,我如何停止对该方法的基本版本的调用,因为它不是覆盖,因此我不能'不'调用 base.OnIsEnabledChanged



感谢alot!

解决方案

同样的问题因为IsHitTestVisible = false,Up-Down键仍然存在。



所以我最后做的是重新使用这样的自定义控件:

  public class FormMainDataGrid:DataGrid 
{
public FormMainDataGrid():base(){
this.IsEnabledChanged + = new DependencyPropertyChangedEventHandler(DataGrid_IsEnabledChanged);
this.SelectionChanged + = new SelectionChangedEventHandler(DataGrid_SelectionChanged);
}

private void DataGrid_SelectionChanged(object sender,SelectionChangedEventArgs args)
{
if(this.IsEnabled)
{
_selectedValue = this 。选择值
}
}

私有对象_selectedValue;

private void DataGrid_IsEnabledChanged(object sender,DependencyPropertyChangedEventArgs args)
{
this.Dispatcher.BeginInvoke((Action)(()=>
{
this.SelectedValue = _selectedValue;
}),null);
}
}

这个工作很好...我只需要要小心,因为当控件被禁用时更改SelectedValue然后将它关闭...



所以总之,我相信你的解决方案是最完整的,但是我允许我将我的表单的代码保持为精简



感谢您的帮助!


I have been struggling with this for a while now. I have a Master / Details layout in my application, and am faced, like many others, with the problem of the DataGrid loosing its selection when disabling it. Essencialy, after selecting an element from the list to populate a series of fields, the user presses "Edit", wich disables the DataGrid and enables all of the form's fields. Pressing the "Save" button will revert these actions after saving the data... Pretty strait forward.

I am on Windows 7 developping with VS 2010 in the .Net Framework 4.

What I have tried:
1) Based on this post, I have tried to use the DataGrid in the June 2009 version of the WPF Toolkit, but I had the same reaction.
2) Based on this WPF CodePlex bug report, I have tried to create a custom control based on the DataGrid and to override the OnIsEnabledChanged call to remove the call to "UnselectAllCells", but with no code example, I can't even get it to fire once. I have tried:

public class FormMainDataGrid : DataGrid
{
    static FormMainDataGrid()
    {
        IsEnabledProperty.OverrideMetadata(typeof(FormMainDataGrid), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged)));
    }

    public FormMainDataGrid() : base() { }

    private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        d.CoerceValue(CanUserAddRowsProperty);
        d.CoerceValue(CanUserDeleteRowsProperty);

        //this was added in new version !!!
        /*
        if (!(bool)(e.NewValue))
        {
            ((DataGrid)d).UnselectAllCells();
        }
        */

        // Many commands use IsEnabled to determine if they are enabled or not
        CommandManager.InvalidateRequerySuggested();
    }
}  

but this still unselects the currently selected row as soon as I disable the DataGrid. I have tried to interprete the last comments (in the Codeplex bug report) like this:

public class FormMainDataGrid : DataGrid
{
    static FormMainDataGrid()
    {

    }

    public static void OverrideStuff() 
    {
        IsEnabledProperty.OverrideMetadata(typeof(FormMainDataGrid), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged)));
    }

    public FormMainDataGrid() : base() { }

    private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        d.CoerceValue(CanUserAddRowsProperty);
        d.CoerceValue(CanUserDeleteRowsProperty);

        //this was added in new version !!!
        /*
        if (!(bool)(e.NewValue))
        {
            ((DataGrid)d).UnselectAllCells();
        }
        */

        // Many commands use IsEnabled to determine if they are enabled or not
        CommandManager.InvalidateRequerySuggested();
    }
}

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        FormMainDataGrid.OverrideStuff();
        base.OnStartup(e);
    }
}  

but that does not even fire the modified version of the method.

First, am-I going the right way for this? Considering that the Deselection is caused by this method, can I completely replace the internal call to 'OnIsEnabledChanged' for my own method? Is there another way I could be tackling this problem? Or more specificly, how can i stop the call to the base version of this method since it is not an override, thus I cannot 'not' call the base.OnIsEnabledChanged?

Thanks alot!

解决方案

The same problem with the Up-Down key still exists with IsHitTestVisible = false.

So what I ended up doing is re-working the custom control like this:

    public class FormMainDataGrid : DataGrid
    {
        public FormMainDataGrid() : base() {
            this.IsEnabledChanged += new DependencyPropertyChangedEventHandler(DataGrid_IsEnabledChanged);
            this.SelectionChanged += new SelectionChangedEventHandler(DataGrid_SelectionChanged);
        }

        private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs args)
        {
            if (this.IsEnabled)
            {
                _selectedValue = this.SelectedValue;
            }
        }

        private object _selectedValue;

        private void DataGrid_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            this.Dispatcher.BeginInvoke((Action)(() =>
            {
                this.SelectedValue = _selectedValue;
            }), null);
        }
    }

This works pretty well... I just have to be carefull because changing the SelectedValue when the control is disable will then put it off track...

So in conclusion, I believe that your solution is the most complete, but mine allows me to keep my form's code as lean & mean as possible.

Thanks for your help!

这篇关于WPF DataGrid - 禁用时保留选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆