2013-03-07 32 views
3

目前,我已經對應該顯示的DataContext對象的屬性(DisplayName)進行了硬編碼。但通常您可以在ComboBox自身中使用DisplayMemberPath屬性指定此路徑。我如何使用DisplayMemberPath指定的值作爲在內容展示器中綁定的屬性?在ComboBoxItem模板中使用DisplayMemberPath

<Style TargetType="{x:Type ComboBoxItem}"> 
     <Setter Property="SnapsToDevicePixels" Value="True" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border x:Name="ItemBorder" 
          Padding="2,0" 
          BorderThickness="1" 
          CornerRadius="3"> 


         <ContentPresenter Content="{Binding DisplayName}"/> 


        </Border> 

        <ControlTemplate.Triggers> 
         <Trigger SourceName="ItemBorder" Property="IsMouseOver" Value="True"> 
          <Setter TargetName="ItemBorder" Property="Background" Value="{StaticResource LightBlueBackgroundBrush}"/> 
          <Setter TargetName="ItemBorder" Property="BorderBrush" Value="{StaticResource LightBlueBackgroundBrush}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

作爲參考,這裏是我的組合框樣式。

<Style TargetType="{x:Type ComboBox}"> 
    <Setter Property="SnapsToDevicePixels" Value="True" /> 
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> 
    <Setter Property="Height" Value="22"/> 
    <Setter Property="Background" Value="White"/> 
    <Setter Property="BorderBrush" Value="{StaticResource MidGreyBorderStroke}"/> 
    <Setter Property="Border.CornerRadius" Value="3" /> 
    <Setter Property="IsEditable" Value="False" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ComboBox}"> 

       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="1" 
         CornerRadius="{TemplateBinding Border.CornerRadius}" 
         Width="{TemplateBinding Width}" 
         Height="{TemplateBinding Height}"> 

        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="Auto" /> 
          <ColumnDefinition Width="Auto" /> 
         </Grid.ColumnDefinitions> 

         <ContentPresenter x:Name="ReadOnlyContentPresenter" 
              Grid.Column="0" 
              Margin="5,0" 
              VerticalAlignment="Center" 
              HorizontalAlignment="Left" 
              Content="{TemplateBinding SelectionBoxItem}" 
              ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
              ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" /> 

         <TextBox x:Name="PART_EditableTextBox" 
           Grid.Column="0" 
           Margin="5,0" 
           VerticalAlignment="Center" 
           HorizontalAlignment="Center" 
           Visibility="Hidden" 
           IsReadOnly="{TemplateBinding IsReadOnly}" /> 

         <Border Grid.Column="1"  
           BorderBrush="{TemplateBinding BorderBrush}" 
           BorderThickness="1,0,0,0" 
           Margin="0,2" /> 

         <ToggleButton Grid.Column="2" 
             Margin="1,0" 
             Background="{TemplateBinding Background}" 
             VerticalAlignment="Center" 
             HorizontalAlignment="Right" 
             Focusable="False" 
             IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 
             ClickMode="Press" 
             Style="{StaticResource ComboBoxToggleButton}"/> 

         <Popup x:Name="PART_Popup" 
           AllowsTransparency="True" 
           Placement="Bottom" 
           IsOpen="{TemplateBinding IsDropDownOpen}" 
           Focusable="False" 
           PopupAnimation="Fade" 
           SnapsToDevicePixels="True"> 

          <Grid Background="Transparent" 
            MinWidth="{TemplateBinding ActualWidth}" 
            MaxHeight="{TemplateBinding MaxDropDownHeight}"> 

           <Border x:Name="DropDownBorder" 
             Background="{TemplateBinding Background}" 
             BorderBrush="{TemplateBinding BorderBrush}" 
             BorderThickness="1" 
             CornerRadius="{TemplateBinding Border.CornerRadius}" 
             Margin="0,2,0,0"> 

            <ScrollViewer Margin="6,0"> 
             <StackPanel IsItemsHost="True" 
                KeyboardNavigation.DirectionalNavigation="Contained" /> 
            </ScrollViewer> 
           </Border> 
          </Grid> 
         </Popup> 
        </Grid> 
       </Border> 

       <ControlTemplate.Triggers> 
        <Trigger Property="IsEnabled" Value="False"> 
         <Setter Property="Opacity" Value=".65" /> 
        </Trigger> 

        <Trigger Property="HasItems" Value="false"> 
         <Setter TargetName="DropDownBorder" Property="MinHeight" Value="42"/> 
        </Trigger> 

        <Trigger Property="IsEditable" Value="True"> 
         <Setter Property="IsTabStop" Value="false"/> 
         <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/> 
         <Setter TargetName="ReadOnlyContentPresenter" Property="Visibility" Value="Hidden"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

回答

8

嗯,這實際上是有一個很簡單的回答一個有趣的問題。

簡短的回答

<ContentPresenter /> 

龍答:

如果已經覆蓋了ComboBoxItem風格,但你仍然要使用從ComboBoxDisplayMemberPath你不必把任何東西插入樣式Content,因爲Parent(ComboBox)將爲您解決此問題。由於DisplayMemberPath只是一個字符串而不是實際的屬性,如果你綁定到DisplayMemberPath所有項目將只顯示任何價值,你把DisplayMemberPath

因此,所有你需要做的是去除ContentComboBoxItem風格結合

實施例:

<Style TargetType="{x:Type ComboBoxItem}"> 
    ............. 
    <Border x:Name="ItemBorder" Padding="2,0" BorderThickness="1" CornerRadius="3"> 
     <ContentPresenter /> <!-- no content binding --> 
    </Border> 

下面是一個簡單的例子,顯示該工作

的Xaml:

<Window x:Class="WpfApplication13.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" x:Name="UI" Width="343" Height="744.625" > 
    <Window.Resources> 
     <Style TargetType="{x:Type ComboBoxItem}"> 
      <Setter Property="SnapsToDevicePixels" Value="True" /> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="ComboBoxItem"> 
         <Border x:Name="ItemBorder" Padding="2,0" BorderThickness="1" CornerRadius="3"> 
          <ContentPresenter /> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 

    <StackPanel DataContext="{Binding ElementName=UI}"> 
     <ComboBox ItemsSource="{Binding Items}" DisplayMemberPath="Name" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/> 
     <ComboBox ItemsSource="{Binding Items}" DisplayMemberPath="State" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/> 
    </StackPanel> 

</Window> 

代碼:

public partial class MainWindow : Window 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 

     for (int i = 0; i < 50; i++) 
     { 
      Items.Add(new ComboBoxModel { Name = "Name" + i, State = "State" + i }); 
     } 
    } 

    private ObservableCollection<ComboBoxModel> _items = new ObservableCollection<ComboBoxModel>(); 
    public ObservableCollection<ComboBoxModel> Items 
    { 
     get { return _items; } 
     set { _items = value; } 
    } 

} 

public class ComboBoxModel 
{ 
    public string Name { get; set; } 
    public string State { get; set; } 
} 

結果:

enter image description hereenter image description here

+0

非常感謝。 – Nathanael 2013-03-08 05:56:28

+0

不錯的答案+1! – failedprogramming 2013-03-08 08:03:22

+1

謝謝,你救了我。重要時刻。我正在努力做到這一點,現在幾個小時,但它只是不想工作。直到我把你的解決方案與我的相比,發現了一個不同的細節:我沒有提供TargetType =「{x :鍵入ComboBoxItem}「到ControlTemplate。當我添加這個時,我突然看到了內容。之後,我在文檔中發現了一個小問題:「另請注意,如果模板定義包含ContentPresenter,則需要在ControlTemplate上使用TargetType屬性。」但不是在ContentPresenter的文檔中(雖然它在示例中) – 2013-06-26 10:24:45

-1

試試這個

<ContentPresenter Content="{TemplateBinding DisplayMemberPath}"/> 
+0

都能跟得上。由於DisplayMemberPath不是ComboBoxItem的屬性,因此您甚至無法以此方式編譯它。如果您使用ComboBox.DisplayMemberPath,則下拉框中不會顯示任何內容。 – Nathanael 2013-03-08 00:39:34

+0

哦,它附屬性... – 2013-03-08 00:40:42