2010-11-15 12 views
5

मैं WPF में एक डेटा ग्रिड का उपयोग कर रहा है और यह केवल अपने स्तंभों की चौड़ाई फिट करने के लिए हटना चाहते हैं। यह प्रारंभिक प्रतिपादन के लिए यह अच्छी तरह से करता है। जब मैं इसे व्यापक बनाने के लिए एक कॉलम का आकार बदलता हूं तो ग्रिड भी बढ़ता है। लेकिन अगर मैं इसे फिर से संकुचित करने के लिए कॉलम का आकार बदलता हूं तो मुझे अपने कॉलम के दाईं ओर सफेद जगह मिलती है (और मैं देख सकता हूं कि कॉलम हेडर ग्रे क्षेत्र कॉलम से परे बढ़ाया गया है।WPF डेटा ग्रिड हटना नहीं करता है जब स्तंभ चौड़ाई सिकुड़ता

मुझे डेटा चाहिए ग्रिड कॉलम के साथ अपनी चौड़ाई को कम करता है इसलिए मुझे दाईं ओर सफेद जगह नहीं मिलती है। मैंने कोड को डीबग करने का प्रयास किया है और जहां तक ​​मैं देख सकता हूं कि समस्या DataGridCellsPanel में है, लेकिन मैं किसी भी जगह को ठीक करने के लिए नहीं देख सकता चौड़ाई माप।

किसी भी मदद की सराहना की जाएगी।

उत्तर

3

मैं वापस थोड़ी देर के लिए कि समस्या थी और मैं तो यह से नाराज है कि मैं इसके लिए एक बदसूरत ठीक कर दिया हो रही थी। यह बहुत नहीं है, लेकिन यह हो जाता है काम किया। सबसे पहले, टी उनकी केवल एक समस्या है जब क्षैतिज स्क्रॉलबार अदृश्य है इसलिए हमें इसके संदर्भ की आवश्यकता होगी। इस कोड को एक बार सभी DataGridColumns लोड हो जाने पर चलाने के लिए होगा (मेरे मामले में, सभी Xaml में है, इसलिए लोडेड घटना) और इसे जोड़ने/ध्यान में DataGridColumns के हटाने के ले नहीं करता, लेकिन यह है कि एक आसान ठीक है।

<DataGrid Name="c_dataGrid" 
      Loaded="c_dataGrid_Loaded" 
      ...> 
    <DataGrid.Columns> 
     <DataGridTextColumn ..."/> 
     <DataGridTextColumn ..."/> 
     <!-- ... --> 

फिर लोडेड eventhandler में हम डेटा ग्रिड ScrollViewer हो और डेटा ग्रिड में हर DataGridColumn की ActualWidthProperty में परिवर्तन के लिए एक श्रोता जोड़ें।

private ScrollViewer m_dataGridScrollViewer = null; 
private void c_dataGrid_Loaded(object sender, RoutedEventArgs e) 
{ 
    m_dataGridScrollViewer = GetVisualChild<ScrollViewer>(c_dataGrid); 
    DependencyPropertyDescriptor dependencyPropertyDescriptor = 
     DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn)); 
    if (dependencyPropertyDescriptor != null) 
    { 
     foreach (DataGridColumn column in c_dataGrid.Columns) 
     { 
      dependencyPropertyDescriptor.AddValueChanged(column, DataGridColumn_ActualWidthChanged); 
     } 
    } 
} 

और फिर हम सब DataGridColumns के आकार से डेटा ग्रिड के आकार की गणना और 8.0 की एक निरंतर जोड़ने (जो अंतर आम तौर पर होता है)।

private void DataGridColumn_ActualWidthChanged(object sender, EventArgs e) 
{ 
    if (m_dataGridScrollViewer != null) 
    { 
     if (m_dataGridScrollViewer.ComputedHorizontalScrollBarVisibility != Visibility.Visible) 
     { 
      double dataGridWidth = 8.0; 
      foreach (DataGridColumn column in c_dataGrid.Columns) 
      { 
       dataGridWidth += column.ActualWidth; 
      } 
      c_dataGrid.Width = dataGridWidth; 
     } 
     else 
     { 
      c_dataGrid.Width = double.NaN; 
     } 
    } 
} 

आप ऐसा करने का एक बेहतर तरीका है के साथ आते हैं तो मुझे पता है :)

public static T GetVisualChild<T>(object parent) where T : Visual 
{ 
    DependencyObject dependencyObject = parent as DependencyObject; 
    return InternalGetVisualChild<T>(dependencyObject); 
} 
private static T InternalGetVisualChild<T>(DependencyObject parent) where T : Visual 
{ 
    T child = default(T); 

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(v); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 
+0

यह एक अच्छा समाधान है। मैंने इसे थोड़ा tweaked किया है ताकि यह इसके बजाय मैक्सविड्थ संपत्ति सेट करता है। यह दृश्य अभिभावक की बाधाओं से परे ग्रिड की समस्या का विस्तार करता है। मैंने इसे बेहतर तरीके से encapsulate करने के लिए इसे एक व्यवहार में भी परिवर्तित कर दिया। – jjrdk

+0

इसके अलावा, यदि DataGridColumn_ActualWidthChanged को नहीं कहा जा रहा है, तो सुनिश्चित करें कि आप Microsoft.Windows.Controls.DataGridColumn का उपयोग करें, न कि System.Windows.Controls.DataGridColumn जब आप निर्भरताप्रॉपर्टी डिस्क्रिप्टर प्राप्त कर रहे हों। – Monsignor

2

एक अच्छा समाधान है कि करते हैं। मैंने इसे थोड़ा tweaked किया है ताकि यह इसके बजाय मैक्सविड्थ संपत्ति सेट करता है। यह दृश्य अभिभावक की बाधाओं से परे ग्रिड की समस्या का विस्तार करता है। मैंने इसे बेहतर तरीके से encapsulate करने के लिए इसे एक व्यवहार में भी परिवर्तित कर दिया।

यह है कि मैं क्या साथ समाप्त हो गया है।

public class UpdateWidthOnColumnResizedBehavior : Behavior<DataGrid> 
{ 
     private static readonly DependencyPropertyDescriptor Descriptor; 

     static UpdateWidthOnColumnResizedBehavior() 
     { 
      Descriptor = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn)); 
     } 

     protected override void OnAttached() 
     { 
      base.OnAttached(); 

      AssociatedObject.Columns.CollectionChanged += OnColumnsCollectionChanged; 

      foreach (var column in AssociatedObject.Columns) 
      { 
       AddListener(column); 
      } 
     } 

     void OnColumnsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
     { 
      switch (e.Action) 
      { 
       case NotifyCollectionChangedAction.Add: 
        foreach (var column in e.NewItems.OfType<DataGridColumn>()) 
        { 
         AddListener(column); 
        } 
        break; 
       case NotifyCollectionChangedAction.Remove: 
        foreach (var column in e.OldItems.OfType<DataGridColumn>()) 
        { 
         RemoveListener(column); 
        } 
        break; 
       case NotifyCollectionChangedAction.Replace: 
        foreach (var column in e.NewItems.OfType<DataGridColumn>()) 
        { 
         AddListener(column); 
        } 
        foreach (var column in e.OldItems.OfType<DataGridColumn>()) 
        { 
         RemoveListener(column); 
        } 
        break; 
      } 
     } 

     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 

      foreach (var column in AssociatedObject.Columns) 
      { 
       RemoveListener(column); 
      } 
     } 

     private void AddListener(DataGridColumn column) 
     { 
      Descriptor.AddValueChanged(column, ResizeGrid); 
     } 

     private void RemoveListener(DataGridColumn column) 
     { 
      Descriptor.RemoveValueChanged(column, ResizeGrid); 
     } 

     private void ResizeGrid(object sender, EventArgs e) 
     { 
      var columnsWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth); 
      AssociatedObject.MaxWidth = columnsWidth + 2; 
      AssociatedObject.InvalidateMeasure(); 
     } 
    } 

मैं अभी भी कुछ चीजें दो ग्रिड की चौड़ाई समन्वय के बारे में पता लौह करने के लिए है, लेकिन यह एक के लिए काम करने के लिए लग रहा है।

+0

बढ़िया लग रहा है, अगली बार मुझे इसकी आवश्यकता होगी! –

0

है अपने दृष्टिकोण दोनों के साथ एक मामूली समस्या लगती है। जब मैं बाईं ओर बाईं ओर सबसे अधिक कॉलम खींचता हूं, तो पूरे ग्रिड को आकार में बदल दिया/घुमाया जा रहा है (दुर्भाग्य से मेरे पास छवि पोस्ट करने के लिए पर्याप्त प्रतिष्ठा नहीं है)।

तो मैं बदलाव कर दिया है jjrdk ResizeGrid समारोह, तो यह पिछले स्तंभ चौड़ाई की गणना और यह बाईं ओर सभी तरह फैली हुई है। ग्रिड क्षैतिज संरेखण और क्षैतिज सामग्री हस्ताक्षर क्षैतिजAignignment.Stretch पर सेट किया जाना चाहिए।

void ResizeGrid(object sender, EventArgs e) 
    { 
     var scroll = ExTreeHelper.FindVisualChild<ScrollViewer>(AssociatedObject); 

     if (scroll != null && null != AssociatedObject.Columns && AssociatedObject.Columns.Count > 0) 
     { 
      var lastColumn = AssociatedObject.Columns.Last(); 

      double dataGridWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth) + 2.0; 

      if (scroll.ComputedHorizontalScrollBarVisibility != Visibility.Visible) 
      { 
       RemoveListener(lastColumn); 

       AssociatedObject.Columns.Last().Width = 
        AssociatedObject.Columns.Last().Width.DisplayValue + scroll.ViewportWidth - dataGridWidth; 

       AssociatedObject.Width = dataGridWidth + scroll.ViewportWidth - dataGridWidth; 

       AddListener(lastColumn); 
      } 
      else 
      { 
       AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch; 
       AssociatedObject.HorizontalContentAlignment = HorizontalAlignment.Stretch; 

       AssociatedObject.Width = double.NaN; 
      } 
     }   } 

मेरे पास एकमात्र मुद्दा यह है कि स्क्रॉल बार हमेशा होता है, भले ही सभी कॉलम फिट हों।

अभी भी एक और मुद्दा है, जब सभी स्तंभों बाईं ओर संक्षिप्त कर दिए जाते है, यह झिलमिलाते शुरू होता है।

क्या इस सफेद जगह से छुटकारा पाने के लिए कुछ भी किया जा सकता है?

लियोन

संबंधित मुद्दे