2009-07-27 9 views
1

je tire la classe DataGridViewEx de DataGridView comme ceci:AutoGenerateColumns DataGridView est définie sur true en quelque sorte

public class DataGridViewEx : DataGridView 
{ 
    // ... 

    [DefaultValue(false)] 
    [Browsable(true)] 
    public new bool AutoGenerateColumns 
    { 
     get { return base.AutoGenerateColumns; } 
     set { base.AutoGenerateColumns = value; } 
    } 

    public DataGridViewEx() 
    { 
     AutoGenerateColumns = false; 
    } 

    // ... 
} 

Mais, quand j'ajouter mon contrôle DataGridViewEx à une forme, je vois que la propriété AutoGenerateColumns est définie sur true! Mon code ne le définit pas n'importe où, donc "quelqu'un d'autre" :) le définit comme vrai. Bien sûr, le code indiqué ci-dessus est exécuté et AutoGenerateColumns est défini sur false pendant un moment, mais plus tard, il devient "true".

Des idées?

Répondre

4

J'ai téléchargé les sources .NET pour être en mesure de débogage framework .NET comme expliqué ici:
http://referencesource.microsoft.com/serversetup.aspx

Puis-je mettre un point d'arrêt sur la propriété de DataGridView.AutoGenerateColumns et a découvert qu'il est défini sur true dans le système. Windows.Forms.Design.DataGridViewDesigner.Initialize() méthode.
I a ouvert cette méthode dans le réflecteur et vu ce qui suit:

public override void Initialize(IComponent component) 
{ 
    ... 
    view.AutoGenerateColumns = view.DataSource == null; 
    ... 
} 

Donc, comme DataSource est nulle, la méthode initialize() définit AutoGeneratedColumns true :(

Je voulais tirer mon propre concepteur de DataGridViewDesigner classe pour remplacer ce comportement, mais DataGridViewDesigner est interne, donc je ne peux pas.

il semble qu'il n'y ait aucun moyen de résoudre ce problème correctement :(

2

C'est à prévoir, malheureusement. Parce que vous déclarez AutogenerateColumns comme new, les appels ne sont pas virtualisés. Lorsque le code parent définit AutogenerateColumns à true, il ne passe pas dans votre setter de propriété. Bien que cela n'ait aucun effet direct sur le comportement (puisque vous ne faites rien d'autre que déférer à la propriété parente), limite votre capacité à déboguer puisque vous ne pouvez pas faire un Console.WriteLine(Environment.StackTrace) ou quelque chose de similaire dans votre setter. Vous aurez probablement besoin soit d'utiliser un outil comme Reflector pour essayer de trouver où il est défini sur true, mais cela sera problématique pour tous les scénarios, sauf les plus simples (par exemple, si le parent définit la variable de support directement). Vous aurez vraiment besoin de faire quelques essais et erreurs pour trouver où la valeur est définie, puis appelez votre code AutoGeneratedColumns = false;. Je remplacer OnCreateControl et inspecter la valeur là comme un début.

2

Cela a également été un problème pour moi. Pour une raison quelconque, la propriété AutogenerateColumns possède un attribut de [Browsable (false)], de sorte qu'il n'apparaîtra pas dans le concepteur. Pour contourner ce problème, je m'assure de définir AutogenerateColumns = False dans le constructeur du formulaire contenant le contrôle DataGridView. Je crois que tant que vous faites cela avant la liaison de données, il devrait fonctionner comme prévu.

2

Ma solution est assez simple: Surveillez les changements de AutoGenerateColumns en remplaçant OnAutoGenerateColumnsChanged et annuler la modification si elle est indésirable:

public class MyDataGridView : DataGridView 
{ 
    private bool mbAutoGenerateColumns = false; 

    [Browsable(true)] 
    [Category("Behavior")] 
    [DefaultValue(false)] 
    new public bool AutoGenerateColumns 
    { 
     get { return base.AutoGenerateColumns; } 
     set { base.AutoGenerateColumns = mbAutoGenerateColumns = value; } 
    } 

    public MyDataGridView() 
    { 
     // Set AGC to false right on the start 
     AutoGenerateColumns = false; 
    } 

    protected override void OnAutoGenerateColumnsChanged(EventArgs e) 
    { 
     base.OnAutoGenerateColumnsChanged(e); 

     // When AGC gets changed, check if the change happened 
     // internally or through the new property. 
     // If internally, revert! 
     // Since DGV has a tendency to enable AGC, only the setting 
     // to false is explicitly needed, the rest happens automatically 
     if(!mbAutoGenerateColumns && base.AutoGenerateColumns) 
      base.AutoGenerateColumns = false; 
    } 
} 

Je sais qu'il est tout à fait un hack, mais il fonctionne et depuis le Concepteur de contrôle - comme mentionné précédemment - n'est pas dérivable , c'est le meilleur que j'ai pu trouver.

Questions connexes