2010-02-02 14 views

Répondre

6

Pour autant que je sais qu'il n'y a aucun moyen intégré pour le faire ... Cependant, vous pouvez utiliser des extensions de balisage pour récupérer une ligne ou une colonne par son nom:

[MarkupExtensionReturnType(typeof(int))] 
public abstract class GridBandExtensionBase : MarkupExtension 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     if (serviceProvider != null) 
     { 
      var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; 
      if (target != null) 
      { 
       var obj = target.TargetObject as DependencyObject; 
       if (obj != null) 
       { 
        var grid = VisualTreeHelper.GetParent(obj) as Grid; 
        if (grid != null) 
        { 
         return GetBandIndex(grid); 
        } 
       } 
      } 
     } 
     return 0; 
    } 

    protected abstract int GetBandIndex(Grid grid); 
} 

public class GridRowExtension : GridBandExtensionBase 
{ 
    public GridRowExtension() {} 

    public GridRowExtension(string rowName) 
    { 
     this.RowName = rowName; 
    } 

    [ConstructorArgument("rowName")] 
    public string RowName { get; set; } 

    protected override int GetBandIndex(System.Windows.Controls.Grid grid) 
    { 
     for (int i = 0; i < grid.RowDefinitions.Count; i++) 
     { 
      if (grid.RowDefinitions[i].Name == RowName) 
      { 
       return i; 
      } 
     } 
     return 0; 
    } 
} 

public class GridColumnExtension : GridBandExtensionBase 
{ 
    public GridColumnExtension() {} 

    public GridColumnExtension(string columnName) 
    { 
     this.ColumnName = columnName; 
    } 

    [ConstructorArgument("columnName")] 
    public string ColumnName { get; set; } 

    protected override int GetBandIndex(System.Windows.Controls.Grid grid) 
    { 
     for (int i = 0; i < grid.ColumnDefinitions.Count; i++) 
     { 
      if (grid.ColumnDefinitions[i].Name == ColumnName) 
      { 
       return i; 
      } 
     } 
     return 0; 
    } 
} 

Vous pouvez ensuite utiliser ces extensions comme suit:

<Button Grid.Row="{my:GridRow Row_Top}" 
     Grid.Column="{my:GridColumn Column_Right}" 
     Content="Hello world" /> 

REMARQUE: si vous compilez ces extensions de balisage dans le même ensemble que votre application, le concepteur ne sera pas en mesure d'appeler le constructeur avec un paramètre (mais il fonctionne très bien à runtime). C'est un known bug que Microsoft n'a pas l'intention de réparer. Si vous voulez que cela fonctionne au moment du design, placez l'extension de balisage dans un assemblage séparé, ou spécifiez les propriétés RowName/ColumnName explicitement, comme suit:

<Button Grid.Row="{my:GridRow RowName=Row_Top}" 
     Grid.Column="{my:GridColumn ColumnName=Column_Right}" 
     Content="Hello world" /> 
+0

Merci Thomas, réponse exceptionnelle! – Brad