2016-06-02 8 views
1

Schalten Sie dieseWie erstellt man WPF ComboBox mit zwei ausgerichteten Spalten (und automatische Breite für die erste)?

http://imgur.com/VZzMe6l] 1

In diese

enter image description here

Ausführliche Beschreibung:

konnte ich es mit diesem fiesen Hack tun (Aggregieren max Spaltenbreite erforderlich) :

// result.Type == typeof(List<MethodInfo>) 
_returnTypeColumnWidth = result.Max(info => new FormattedText(info.ReturnType.Name, CultureInfo.CurrentCulture, WindowsFlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, MediaBrushes.Black).Width); 

und bindende erste Kontrolle (in einer ComboBox.ItemTemplate) Breite dazu.

Die Frage ist: Wie geht es mit MVVM?

war meine Idee MinWidth von einem Eltern Eigentum zu erhalten (die mit Breite Änderungen aktualisiert werden):

<ComboBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock 
       Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type sd:InvokeMethodDesigner}}, Path=ReturnTypeColumnWidth, Mode=OneWayToSource}" 
       MinWidth="{Binding RelativeSource={RelativeSource AncestorType={x:Type sd:InvokeMethodDesigner}}, Path=ReturnTypeColumnWidth, Mode=OneWay}" 
       Margin="0,0,4,0" 
       TextAlignment="Right" Text="{Binding ReturnType.Name}" /> 
      <TextBlock Text="{Binding Path=., Converter={StaticResource MethodInfoNameConverter}}" /> 
     </StackPanel> 
    </DataTemplate> 
</ComboBox.ItemTemplate> 

C#:

public double ReturnTypeColumnWidth 
{ 
    get { return _returnTypeColumnWidth; } 
    set 
    { 
     if(Double.IsNaN(value) || (value <= _returnTypeColumnWidth)) 
      return; 
     _returnTypeColumnWidth = value; 
     RaisePropertyChanged("ReturnTypeColumnWidth"); 
    } 
} 

Aber die ReturnTypeColumnWidth_set() wird nur einmal aufgerufen, während der TextBlock-Initialisierung (Wert ist NaN).

+0

Anstelle von 'StackPanel' verwenden Sie' Grid' mit definierten 2 Spalten. – XAMlMAX

+1

MVVM! = Kein Codebehind. Es bedeutet keine Geschäftslogik im Codebehind. UI-Logik gehört dort. – Will

Antwort

2

Sie können unterschiedliche Grid s erhalten, um die Spalten- oder Reihenautomatik untereinander zu teilen, indem Sie die angehängten Eigenschaften Grid.IsSharedSizeScope und Grid.SharedSizeGroup verwenden. Das macht genau das, was Sie versuchen, aber jemand anderes hat den Code bereits geschrieben. Wenn Sie es selbst schreiben müssten, würde ich empfehlen, es mit angehängten Eigenschaften zu tun - oder wenn Sie es wirklich eilig haben, vielleicht sogar im Code hinterher kludeln. Wie Will in Kommentaren feststellt, gehört diese Logik vollständig zur Ansicht. Je weniger das Anzeigemodell die Anzeigespaltenbreiten kennt oder berücksichtigt, desto besser.

<ComboBox 
    ... 
    Grid.IsSharedSizeScope="True" 
    ... 
    > 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition 
         Width="Auto" 
         Grid.SharedSizeGroup="ReturnTypeNameColumn" 
         /> 
        <ColumnDefinition 
         Width="*" 
         /> 
       </Grid.ColumnDefinitions> 
       <TextBlock 
        Grid.Column="0" 
        Margin="0,0,4,0" 
        TextAlignment="Right" 
        Text="{Binding ReturnType.Name}" 
        /> 
       <TextBlock 
        Grid.Column="1" 
        Text="{Binding Path=., Converter={StaticResource MethodInfoNameConverter}}" 
        /> 
      </Grid> 
     </DataTemplate> 
    <ComboBox.ItemTemplate> 
</ComboBox> 

Möglicherweise müssen ItemsPanel setzen und setzen Grid.IsSharedSizeScope auf dem StackPanel Sie für die Artikel-Host verwenden, sondern versuchen, diese erste und sehen, wie es geht.

+0

Funktioniert wie ein Charme. Danke vielmals! –

Verwandte Themen