2009-08-29 29 views
10

Tôi đã có một danh sách WPF ListView/GridView spec'd trong XAML. Cột đầu tiên sử dụng một CellTemplate để xác định các biểu tượng và những người khác sử dụng DisplayMemberBinding để tự cư trú. Cột biểu tượng rộng 20, các biểu tượng 16 nhưng chúng bị cắt bớt theo lề/đệm/thứ gì đó. Tôi không thể tìm ra nơi nó được đặt.Vị trí lề/đệm được đặt trên GridView ListView của wpf ở đâu?

Đây là yếu tố cần thiết (tôi đã xóa một số cột vì họ giống nhau):

<ListView.ItemContainerStyle> 
    <Style TargetType="{x:Type ListViewItem}"> 
     <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
     <Setter Property="FontWeight" Value="Normal" /> 
     <Style.Triggers> 
      <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="FontWeight" Value="Bold" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</ListView.ItemContainerStyle> 

<ListView.Resources> 
    <DataTemplate x:Key="image"> 
     <Image Width="16" Height="16" Margin="0,0,0,0" 
          HorizontalAlignment="Center" 
          Source="{Binding Path=ObjectType, 
              Converter={StaticResource imageConverter} }" /> 
    </DataTemplate> 
</ListView.Resources> 

<ListView.View> 
    <GridView> 
     <GridViewColumn Width="20" 
         CellTemplate="{StaticResource image}"/> 
     <GridViewColumn Width="120" Header="Name" 
         DisplayMemberBinding="{Binding Path=Name}"/> 
    </GridView> 
</ListView.View> 

ImageConverter chỉ quay một ObjectType thành một hình ảnh để từng loại mặt hàng có biểu tượng riêng.

Trả lời

6

Sử dụng Snoop để tìm ra yếu tố nào chịu trách nhiệm áp đặt khoảng cách thừa. Di chuột qua không gian và giữ quyền kiểm soát và dịch chuyển. Phần tử này sau đó sẽ được tô sáng trong cây trực quan.

+0

Đẹp nhất, cảm ơn. – serialhobbyist

8

theo mặc định, mỗi ô có tỷ lệ được mã hóa là 6.0. Có lẽ đó là vấn đề của bạn. Bạn có thể ghi đè hành vi này bằng cách đặt lề của -6,0 trong ô di động của bạn

37

Nhiều tính năng của GridView được mã hóa cứng vào lớp. Cụ thể là GridViewRowPresenter tạo ra một thùng chứa TextBlock hoặc ContentPresenter được mã hóa cứng cho mỗi ô và buộc các lề tới 6.0,6,0 cho dù bạn có thích hay không.

Thông thường, tôi sẽ ngăn cản bạn từ bất kỳ thứ gì liên quan đến việc viết mã cứng một lề âm để bù lại vì đó là một hack được xếp vào một lần hack khác. Tuy nhiên, sau khi tháo GridViewRowPresenter, không có tùy chọn nào khác.

Nỗ lực đầu tiên của tôi là ghi đè kiểu ẩn cho điều khiển vùng chứa được tạo trong lớp GridViewRowPresenter, nhưng điều khiển đó là một TextBox hoặc một ContentPresenter không có mẫu để ghi đè.

Nỗ lực thứ hai của tôi là để tháo rời mã và tạo một GridViewRowPresenter mới. Tôi e rằng có quá nhiều cuộc gọi 'nội bộ' loạn luân trong lớp để làm cho giải pháp này trở thành một giải pháp khả thi.

Kiến trúc sư thông minh hơn sẽ cung cấp DependencyProperty cho phép người dùng của lớp ghi đè vùng chứa đã được tạo cho từng ô. Đối với một số lý do họ cho phép điều này với các tiêu đề, nhưng không cho phép nội dung tế bào thực tế.

Vì vậy, chúng tôi còn lại với thực tế là các tế bào trong một GridRowPresenter không thể được ghi đè, đảo ngược thiết kế, cũng không templated. Tôi xin lỗi, nhưng lợi nhuận tiêu cực là tốt nhất có thể được thực hiện với lớp này.

Chúng tôi cần một ListView tốt hơn: GridView không phù hợp với giao diện vô nghĩa mặc dù tôi đánh giá cao những gì mà kiến ​​trúc sư ban đầu đang cố gắng thực hiện bằng cách ly dị ItemsPresenter từ bản trình bày.

0

Tôi đã phát triển giải pháp dựa trên hack của Ian Griffiths (http://www.interact-sw.co.uk/iangblog/2007/05/30/wpf-listview-column-margins). Việc kiểm soát nào sau đây:

  • bộ mã hóa cứng Margin cho TextBlock hoặc ContentPresenter tạo ra bởi GridViewRowPresenter đến tài sản phụ thuộc Padding của kiểm soát này
  • truyền HorizontalAlignment của kiểm soát này và VerticalAlignment để đựng nó
  • resets Margin/Padding cho các thùng chứa ListViewItem/GridViewRowPresenter.

Vì vậy, nó cung cấp cho bạn một loại kiểm soát các giá trị được mã hóa cứng.

Mã số: sử dụng

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace Put.Your.Namespace.Here 
{ 
    /// <summary> 
    /// Class allows for reseting hard coded ListViewItem margins and paddings 
    /// </summary> 
    public class ListViewCustomizableCellPresenter : Decorator 
    { 
     protected override void OnVisualParentChanged(DependencyObject oldParent) 
     { 
     base.OnVisualParentChanged(oldParent); 

     var cp = VisualTreeHelper.GetParent(this) as FrameworkElement; 
     if (cp != null) 
     { 
      cp.Margin = Padding; 
      cp.VerticalAlignment = VerticalAlignment; 
      cp.HorizontalAlignment = HorizontalAlignment; 
     } 

     ResetGridViewRowPresenterMargin(); 
     ResetListViewItemPadding(); 
     } 

     private T FindInVisualTreeUp<T>() where T : class 
     { 
     DependencyObject result = this; 
     do 
     { 
      result = VisualTreeHelper.GetParent(result); 
     } 
     while (result != null && !(result is T)); 
     return result as T; 
     } 

     private void ResetGridViewRowPresenterMargin() 
     { 
     var gvrp = FindInVisualTreeUp<GridViewRowPresenter>(); 
     if (gvrp != null) 
      gvrp.Margin = new Thickness(0); 
     } 

     private void ResetListViewItemPadding() 
     { 
     var lvi = FindInVisualTreeUp<ListViewItem>(); 
     if (lvi != null) 
      lvi.Padding = new Thickness(0); 
     } 

     /// <summary> 
     /// Padding dependency property registration 
     /// </summary> 
     public static readonly DependencyProperty PaddingProperty = 
     DependencyProperty.Register("Padding", typeof(Thickness), typeof(ListViewCustomizableCellPresenter), new PropertyMetadata(default(Thickness))); 

     /// <summary> 
     /// Padding dependency property 
     /// </summary> 
     public Thickness Padding 
     { 
     get { return (Thickness)GetValue(PaddingProperty); } 
     set { SetValue(PaddingProperty, value); } 
     } 
    } 

} 

mẫu trong XAML (bên trong định nghĩa của GridViewColumn):

<GridViewColumn.CellTemplate> 
    <DataTemplate> 
     <yourxamlnamespacehere:ListViewCustomizableCellPresenter Padding="0" 
                 VerticalAlignment="Center"> 
      <YourControlOrPanelHere /> 
     </yourxamlnamespacehere:ListViewCustomizableCellPresenter> 
    </DataTemplate> 
</GridViewColumn.CellTemplate> 
1

Kể từ khi biên độ là một cứng mã hoá liên tục, chỉ có giải pháp là sử dụng Reflexion để thay đổi nó bằng tay.

Trong VB:

' Hack : 
    ' Changes the default margin for the GridView's Column. 
    Dim GridViewCellMarginProperty = GetType(GridViewRowPresenter).GetField("_defalutCellMargin", BindingFlags.NonPublic Or BindingFlags.Static Or BindingFlags.GetField) 
    If (GridViewCellMarginProperty IsNot Nothing) Then 
     GridViewCellMarginProperty.SetValue(Nothing, New Thickness(2, 0, 2, 0)) 
    End If 

Nó hoạt động tốt trên dự án của tôi.

Các vấn đề liên quan