2011-11-04 21 views
9

Vì vậy, tôi đã trải qua một số câu hỏi trên trang web và dường như tôi không thể tìm thấy câu trả lời.Mẫu tùy chỉnh cho ComboBox bỏ qua việc sử dụng DisplayMemberPath

Tôi có ComboBox. Nó hoạt động tốt. Tôi quyết định tôi cần phải sửa chữa lớn xuất hiện, vì vậy tôi tạo ra một bản sao của mẫu ComboBox mặc định (đây là một bản sao thẳng, không có sửa đổi):

<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> 

Bây giờ, khi tôi chọn một mục từ danh sách của tôi (đó là một bộ sưu tập các POCO), nó hiển thị không gian tên và tên lớp thay vì giá trị mà nó được cho là.

Nghiên cứu và thử nghiệm của tôi đã khiến tôi tin rằng vấn đề là mẫu mới của tôi không sử dụng thuộc tính DisplayMemberPath. Tôi đã cố gắng để thiết lập một ItemTemplate bằng cách ghi đè phương pháp OnDisplayMemberPathChanged, nhưng điều đó dẫn đến lỗi khi tôi chọn một mục từ danh sách.

Tôi cũng đã thấy mọi người đặt số ItemTemplate qua XAML, nhưng tôi có hàng trăm combobox và tôi không muốn làm điều đó.

Có cách nào để sử dụng thuộc tính DisplayMemberPath trong ControlTemplate của tôi hay một số mã tôi có thể chạy trong điều khiển dẫn xuất để đạt được kết quả mong muốn của mình không?

Trả lời

19

Đó là không một bản sao chính xác, có một điều quan trọng là mất tích trong phần tử này:

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

Có lẽ bạn vô tình xóa nó, cụ thể là:

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 

Nếu bạn không có điều này đặt DisplayMemberPath sẽ không hoạt động vì chọn ComboBox giữa các mẫu bằng cách sử dụng công cụ chọn mẫu (vì bạn có thể sử dụng ItemTemplate hoặc DisplayMemberPath).

+0

Dude! Điều đó hoàn toàn hiệu quả. Tôi chưa bao giờ thấy giải pháp đó mặc dù, và tôi 100% tích cực nó không bao giờ được tạo ra. Tôi đã thực hiện quá trình này 3 hoặc 4 lần, và kiểm tra điểm số của những người có cùng một vấn đề. Điều này hoàn toàn phải là một lỗi về phía Microsoft ... Cảm ơn bạn! – CamronBute

+0

Bây giờ niềm vui đã lắng xuống, tôi phải hỏi làm thế nào bạn tìm ra điều đó. Bạn đang sử dụng gì để tạo các bản sao mẫu? – CamronBute

+3

@CamronBute: Vâng, tôi luôn có các mẫu mặc định mà bạn có thể nhận được [trên MSDN] (http://msdn.microsoft.com/en-us/library/aa970773.aspx) ('Liên kết Default WPF Themes') tại tay, vì vậy tôi đã kiểm tra nó ra để xem mọi thứ đang bị ràng buộc như thế nào. Không khó để thấy rằng 'ContentPresenter' này là thành phần quan trọng cho mục được chọn vì vậy nếu có lỗi thì nó sẽ ở đó, sau đó tôi chỉ cần so sánh nó với bạn để thấy rằng thuộc tính này bị thiếu. Tôi cũng đã thử nghiệm hiệu quả của việc loại bỏ tài sản đó bản thân mình và như mong đợi nó chỉ cho thấy tên loại. –

1

Tôi đã có same question và hóa ra thiết lập DisplayMemberPath chỉ đơn giản là một cách tắt để đặt ItemTemplate thành một giá trị đó trong đó TextBlock.

Do đó, khi bạn đặt ItemTemplate thì DisplayMemberPath trở nên vô dụng vì bạn đã ghi đè TextBlock mặc định bằng giá trị mà nó thêm.

+0

Kiểm tra câu trả lời ở trên. Tôi thấy vấn đề của bạn trong một câu hỏi liên quan, nhưng giải pháp trên hoạt động cho tôi! Cảm ơn anyway, mặc dù :) – CamronBute

+0

Tôi đã sử dụng giải pháp của H.B. nhưng kết quả là câu trả lời này, cố gắng 'ContentTemplate =" {TemplateBinding ItemTemplate} "' cũng làm việc - mặc dù tôi không bận tâm để nó đủ lâu để kiểm tra bất kỳ tác dụng phụ nào. – OhBeWise

0

Tôi đã gặp vấn đề tương tự, đây phải là lỗi, tôi sẽ thử báo cáo lỗi đó.

Khi bạn "chỉnh sửa một bản sao" của mẫu điều khiển từ Visual Studio, nó nhớ dòng:

ContentTemplateSelector = "{TemplateBinding ItemTemplateSelector}"

nào gây ra "DisplayMemberPath" không hoạt động đúng.

0

Tôi biết đây là một câu hỏi cũ, nhưng tôi phải đối mặt với cùng một vấn đề trong những ngày này và tôi cố định nó thêm

ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"

thay vì

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"

1

Hãy chắc chắn rằng bạn không bỏ lỡ ContentTemplateThuộc phần tử.

Đối với combox mẫu bản thân nó nên là:

ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 

Đối với ItemsContainerStyle nó nên là:

ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"   
Các vấn đề liên quan