2011-11-04 11 views
9

Quindi ho trovato diverse domande sul sito e non riesco a trovare la risposta.Il modello personalizzato per ComboBox ignora l'utilizzo di DisplayMemberPath

Ho un ComboBox. Stava funzionando bene. Decido che ho bisogno di rivedere l'aspetto, in modo da creare una copia del modello predefinito ComboBox (si tratta di una copia diretta, nessuna modifica):

<ControlTemplate x:Key="ComboBoxControlTemplate2" TargetType="{x:Type ComboBox}"> 
      <Grid x:Name="MainGrid" SnapsToDevicePixels="True"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="*"/> 
        <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/> 
       </Grid.ColumnDefinitions> 
       <Popup x:Name="PART_Popup" AllowsTransparency="True" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"> 
        <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}"> 
         <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"> 
          <ScrollViewer x:Name="DropDownScrollViewer"> 
           <Grid RenderOptions.ClearTypeHint="Enabled"> 
            <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0"> 
             <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=DropDownBorder}" Height="{Binding ActualHeight, ElementName=DropDownBorder}" Width="{Binding ActualWidth, ElementName=DropDownBorder}"/> 
            </Canvas> 
            <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
           </Grid> 
          </ScrollViewer> 
         </Border> 
        </Microsoft_Windows_Themes:SystemDropShadowChrome> 
       </Popup> 
       <ToggleButton BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"> 
        <ToggleButton.Style> 
         <Style TargetType="{x:Type ToggleButton}"> 
          <Setter Property="OverridesDefaultStyle" Value="True"/> 
          <Setter Property="IsTabStop" Value="False"/> 
          <Setter Property="Focusable" Value="False"/> 
          <Setter Property="ClickMode" Value="Press"/> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" SnapsToDevicePixels="True"> 
              <Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> 
               <Path x:Name="Arrow" Data="M0,0L3.5,4 7,0z" Fill="Black" HorizontalAlignment="Center" Margin="3,1,0,0" VerticalAlignment="Center"/> 
              </Grid> 
             </Microsoft_Windows_Themes:ButtonChrome> 
             <ControlTemplate.Triggers> 
              <Trigger Property="IsChecked" Value="True"> 
               <Setter Property="RenderPressed" TargetName="Chrome" Value="True"/> 
              </Trigger> 
              <Trigger Property="IsEnabled" Value="False"> 
               <Setter Property="Fill" TargetName="Arrow" Value="#FFAFAFAF"/> 
              </Trigger> 
             </ControlTemplate.Triggers> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </ToggleButton.Style> 
       </ToggleButton> 
       <ContentPresenter ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
      </Grid> 
      <ControlTemplate.Triggers> 
       <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="True"> 
        <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/> 
        <Setter Property="Color" TargetName="Shdw" Value="#71000000"/> 
       </Trigger> 
       <Trigger Property="HasItems" Value="False"> 
        <Setter Property="Height" TargetName="DropDownBorder" Value="95"/> 
       </Trigger> 
       <Trigger Property="IsEnabled" Value="False"> 
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
        <Setter Property="Background" Value="#FFF4F4F4"/> 
       </Trigger> 
       <Trigger Property="IsGrouping" Value="True"> 
        <Setter Property="ScrollViewer.CanContentScroll" Value="False"/> 
       </Trigger> 
       <Trigger Property="CanContentScroll" SourceName="DropDownScrollViewer" Value="False"> 
        <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/> 
        <Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 

Ora, quando seleziono un elemento dalla mia lista (che è una raccolta di POCO), visualizza lo spazio dei nomi e il nome della classe invece del valore che si suppone.

La mia ricerca e sperimentazione mi hanno portato a credere che il problema è che il mio nuovo modello non utilizza la proprietà DisplayMemberPath. Ho provato a impostare uno ItemTemplate sostituendo il metodo OnDisplayMemberPathChanged, ma questo si traduce in errori quando seleziono un elemento dall'elenco.

Ho anche visto persone impostare ItemTemplate tramite XAML, ma ho centinaia di caselle combinate e non voglio farlo.

C'è un modo per utilizzare la proprietà DisplayMemberPath nel mio ControlTemplate o un codice che potrei eseguire in un controllo derivato per ottenere il risultato desiderato?

risposta

19

Questo è non una copia esatta, una cosa importante manca in questo elemento:

<ContentPresenter ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
     Content="{TemplateBinding SelectionBoxItem}" 
     ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" 
     HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
     IsHitTestVisible="False" 
     Margin="{TemplateBinding Padding}" 
     SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
     VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> 

Forse accidentalmente eliminato, vale a dire:

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 

Se non si dispone di questo impostare DisplayMemberPath non funzionerà perché lo ComboBox seleziona tra i modelli utilizzando un selettore di modelli (come è possibile utilizzare ItemTemplate o DisplayMemberPath).

+0

Amico! Questo ha funzionato completamente. Non ho mai visto questa soluzione, e sono al 100% positivo che non sia mai stata generata. Ho fatto questo processo 3 o 4 volte e ho controllato decine di persone con lo stesso problema. Questo deve essere totalmente un bug da parte di Microsoft ... Grazie! – CamronBute

+0

Ora che la gioia si è placata, devo chiedervi come l'avete capito. Cosa stai utilizzando per generare copie del modello? – CamronBute

+3

@CamronBute: Beh, ho sempre i modelli predefiniti che è possibile ottenere [su MSDN] (http://msdn.microsoft.com/en-us/library/aa970773.aspx) (link "Temi predefiniti WPF") a mano, così ho controllato per vedere come sono legate le cose. Non è difficile vedere che questo 'ContentPresenter' è il componente chiave per l'elemento selezionato, quindi se c'è un errore dovrebbe essere lì, quindi ho solo bisogno di confrontarlo con il tuo per vedere che questa proprietà mancava. Ho anche provato l'effetto di rimuovere me stesso quella proprietà e come previsto ha mostrato solo il nome del tipo. –

1

Ho avuto il same question, e si scopre modificando la DisplayMemberPath è semplicemente un modo scorciatoia per impostare la ItemTemplate ad un TextBlock con quel valore in esso.

Per questo motivo, quando si imposta ItemTemplate allora DisplayMemberPath diventa inutile perché si è sovrascritto il TextBlock predefinito con il valore aggiunto.

+0

Controllare la risposta di cui sopra. Ho visto il tuo problema in una domanda correlata, ma la soluzione di cui sopra funziona per me! Grazie comunque, però :) – CamronBute

+0

Ho usato la soluzione di H.B. ma, a seguito di questa risposta, anche il tentativo di 'ContentTemplate =" {TemplateBinding ItemTemplate} "ha funzionato, anche se non mi sono preoccupato di lasciarlo abbastanza a lungo per testare eventuali effetti collaterali. – OhBeWise

0

Ho incontrato lo stesso problema, questo dovrebbe essere un bug, proverò a segnalarlo.

Quando si "modificare una copia" del modello di controllo da Visual Studio, si trova la riga:

ContentTemplateSelector = "{} TemplateBinding ItemTemplateSelector"

che ha causato "DisplayMemberPath" non funziona correttamente.

0

So che questa è una vecchia questione, ma ho affrontato lo stesso problema in questi giorni e ho riparato aggiungendo

ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"

invece di

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"

1

Assicurarsi che non manca il Elementi ContentTemplateSelector.

Per il modello combox in sé dovrebbe essere:

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 

Per l'ItemsContainerStyle dovrebbe essere:

ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"   
Problemi correlati