2011-04-07 12 views
21

स्क्रॉल रखें मैं WPF में स्तंभों ControlTemplate और GridViewRowPresenter की एक StackPanel उपयोग करने के साथ एक treeview कार्यान्वित किया। मैंने इस आलेख का पालन किया: http://blogs.msdn.com/b/atc_avalon_team/archive/2006/03/01/541206.aspxएक treeview के सबसे बाईं ओर कॉलम देखा, जबकि क्षैतिज

यह पूरी तरह से काम करता है!

हालांकि, मैं जबकि क्षैतिज स्क्रॉलिंग बाएँ कॉलम (नाम) के साथ रखने के लिए दिखाई दे चाहते हैं।

यह पहले कॉलम पर माइक्रोसॉफ़्ट एक्सेल पर 'फ्रीज पैन' जैसा होगा।

एक विचार, कोई भी?

धन्यवाद फ्रेडेरिक

+4

यह स्क्रॉलव्यूअर को केवल दाएं कॉलम पर लागू करके हासिल किया जा सकता है, फिर बाएं कॉलम पर एक अदृश्य स्क्रॉलव्यूवर लागू करें और लंबवत स्थिति को बांधें। लेकिन कोड को हल करने के लिए इसे अधिक समय की आवश्यकता होगी। – vorrtex

+0

वह उत्तर नहीं जिसे आप चाहते थे, लेकिन जब मैंने आपका प्रश्न देखा और मैं पुष्टि कर सकता हूं कि उनका डब्ल्यूपीएफ ट्रीलिस्ट वास्तव में वही करता है जो आप चाहते हैं तो मैं DevExpress के WPF डेमो के साथ खेल रहा था। वास्तव में आप बाएं या दाएं किसी भी कॉलम को ठीक कर सकते हैं। कॉलम सॉर्टिंग के साथ भी copes। –

उत्तर

5

GridViewRowPresenter समाधान के साथ समस्या यह है कि पेड़ अन्य स्तंभों से विकट है। मुझे लगता है कि आपको इसे अलग होने की आवश्यकता है ताकि आप कॉलम के आस-पास क्षैतिज-केवल ScrollViewer डाल सकें, और मुझे संदेह है कि आपके द्वारा लिंक किए गए आलेख में प्रोजेक्ट को करना आसान है (यदि संभव हो)।

यह प्रोजेक्ट जिसे मैंने कुछ समझने के लिए एक साथ थप्पड़ मार दिया है, किनारों के चारों ओर काफी मोटा है। ऐसे कई मुद्दे हैं जिन्हें आपको अलग-अलग काम करने की आवश्यकता होगी कि मैंने ठीक-ठीक नहीं किया:

  1. टेम्पलेट्स और स्टाइलिंग ताकि लाइनें मिलें, और अन्य दृश्य tweaks।
  2. हेडर और कॉलम के लिए लिंक किए गए प्रोजेक्ट के GridView पहलुओं को पुन: पेश करना।
  3. पहले कॉलम (पेड़ युक्त) के आकार को समायोजित करने के लिए एक स्प्लिटर।

लेख प्रोजेक्ट की तरह, मैंने डेटा स्रोत के रूप में Type ऑब्जेक्ट्स का पेड़ इस्तेमाल किया।

काम करने के लिए इस प्राप्त करने में कोई ExpandingContainer वस्तु में डेटा वस्तुओं लपेटकर था की जड़। ,

public class ExpandingContainer : INotifyPropertyChanged { 
    public object Payload { get; private set; } 

    public ObservableCollection<ExpandingContainer> Children { get; private set; } 

    public ExpandingContainer(object payload) { ... } 

    private bool _isexpanded; 
    public bool IsExpanded { 
     get { return _isexpanded; } 
     set { 
      if (value == _isexpanded) 
       return; 
      _isexpanded = value; 
      PropertyChanged.Notify(() => IsExpanded); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged = (o,e) => {}; 
} 

XAML के रूप में पहले के रास्ते से बाहर कुछ संसाधनों मिलता है: इस INPC वर्ग के बारे में महत्वपूर्ण बातें IsExpanded संपत्ति (बंधन के लिए) और बच्चों का संग्रह है

<!-- bind ExpandingContainer.IsExpanded to TreeViewItem.IsExpanded --> 
<Style TargetType="TreeViewItem"> 
    <Setter Property="IsExpanded" 
      Value="{Binding IsExpanded, Mode=TwoWay}" /> 
</Style> 

<!-- for binding ExpandingContainer.IsExpanded to visibility later --> 
<BooleanToVisibilityConverter x:Key="boolvis" /> 

<!-- the TreeViewItems should display the Type's name --> 
<HierarchicalDataTemplate DataType="{x:Type loc:ExpandingContainer}" 
          x:Key="treeViewSide" 
          ItemsSource="{Binding Children}"> 
    <TextBlock Text="{Binding Payload.Name}" /> 
</HierarchicalDataTemplate> 

<!-- the column side are naively simple, the ItemsControl of children has its 
    visibility bound to ExpandingContainer, but the "columns" are just 
    StackPanels of TextBlocks --> 
<HierarchicalDataTemplate DataType="{x:Type loc:ExpandingContainer}" 
          x:Key="columnSide"> 
    <StackPanel> 
     <StackPanel.Resources> 
      <Style TargetType="TextBlock"> 
       <Setter Property="Margin" Value="10,0" /> 
      </Style> 
     </StackPanel.Resources> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Payload.IsAbstract}" /> 
      <TextBlock Text="{Binding Payload.Namespace}" /> 
      <TextBlock Text="{Binding Payload.GUID}" /> 
     </StackPanel> 
     <ItemsControl ItemsSource="{Binding Children}" 
         Visibility="{Binding IsExpanded, Converter={StaticResource boolvis}}" /> 
    </StackPanel> 
</HierarchicalDataTemplate> 

<!-- a style can't refer to itself, so this was just to apply it to all ItemsControls --> 
<Style TargetType="ItemsControl"> 
    <Setter Property="ItemTemplate" 
      Value="{StaticResource columnSide}" /> 
</Style> 

मैं मूल रूप से केवल ऊर्ध्वाधर ScrollViewer कि TreeView के लिए जिम्मेदार था अंदर सही वाले कॉलम क्षैतिज केवल ScrollViewer घोंसला बनाने से करने की कोशिश की, लेकिन वह अजीब आवश्यकता है कि आप नीचे करने के लिए स्क्रॉल करने के लिए क्षैतिज स्क्रॉल करने के लिए किया था का उत्पादन किया। तो मैंने उन्हें ScrollViewer एस साइड-बाय-साइड रखकर आगे अलग कर दिया।

लंबवत स्क्रॉलबार को दूर दाईं ओर रखने के लिए, मैंने TreeView के चारों ओर स्क्रॉलबार छुपाए और कॉलम के आस-पास केवल स्क्रॉलबार का उपयोग किया। वर्टिकल स्क्रॉलिंग को सिंक करना कोड-बैक में किया जाता है, लेकिन इसे करने के लिए एक और एमवीवीएम तरीका के लिए, आप एक-दूसरे को बाध्य करने में सुविधा के लिए एक संलग्न व्यवहार कर सकते हैं।

<DockPanel> 
    <ScrollViewer VerticalScrollBarVisibility="Hidden" 
        HorizontalScrollBarVisibility="Hidden" 
        DockPanel.Dock="Left" 
        Name="treescroller"> 
     <TreeView ItemsSource="{Binding Items}" 
        ItemTemplate="{StaticResource treeViewSide}" 
        Padding="0,0,0,20"> 
     </TreeView> 
    </ScrollViewer> 
    <ScrollViewer Name="columnscroller" 
        HorizontalScrollBarVisibility="Auto" 
        VerticalScrollBarVisibility="Auto" 
        ScrollChanged="columnscroller_ScrollChanged"> 
     <ItemsControl ItemsSource="{Binding Items}" /> 
    </ScrollViewer> 
</DockPanel> 

और अंत में, कोड-पीछे (ऋण DataContext संपत्ति डेटा वस्तुओं बनाने और स्थापित करने) के महत्वपूर्ण बिट:

private void columnscroller_ScrollChanged(object sender, ScrollChangedEventArgs e) { 
    treescroller.ScrollToVerticalOffset(columnscroller.VerticalOffset); 
} 

आशा है कि यह मदद करता है, या कम से कम एक अलग दृष्टिकोण प्रदान करता है।

मैं वास्तव में एक अच्छा एक है कि भरा हर जरूरत मैं एक संकर TreeView + ListView के लिए के बारे में सोच सकता है, मैं शायद पहले आवश्यक समय खर्च एक देसी समाधान पॉलिश करने से पहले पेशेवर नियंत्रण को देखो चाहते हैं की जरूरत है। इस तरह की चीज बेहतर है जब इस तरह के प्रदर्शन की आवश्यकताएं सरल होती हैं।

+0

+1: आपका उत्तर कल्पना के लिए बहुत कुछ छोड़ देता है, इसमें सिंटैक्स त्रुटियां शामिल हैं (उदा। 'सेटर प्रॉपर्टी = "मार्जिन" '), और आपकी निर्दिष्ट सीमाएं हैं। फिर भी, मुझे यह काम मिल गया और यह ** समस्या को हल करने के लिए एक व्यवहार्य दृष्टिकोण प्रदर्शित करता है **। महान काम और आपने वास्तव में इस पर बक्षीस अर्जित किया! –

+0

सेटर फिक्स्ड। समय के लिए कुछ चीजें छोड़ी गईं, कुछ क्योंकि वे प्रासंगिक नहीं थे। स्तंभों को सही तरीके से करने के अलावा (सप्ताहांत पर ऐसा कर सकते हैं), क्या आपको लगता है कि कुछ भी जोड़ा जाना चाहिए या अन्यथा कल्पना के लिए नहीं छोड़ा गया है? –

+0

एक संक्षिप्त और उपभोग योग्य उत्तर प्रदान करना हमेशा कठिन होता है और यह प्रश्न इसे दोगुना बनाता है। जो भी ** ** को इस प्रश्न का उत्तर देने की आवश्यकता है, उसे आपके उत्तर के साथ गुलाबी रंग दिया जाएगा। लेकिन चूंकि मैंने उन बक्षीस बिंदुओं को छोड़ दिया, इसलिए मैंने अपनी प्रशंसा के लिए थोड़ी आलोचना की। भविष्य के सवालों पर बस अच्छा काम जारी रखें! –

2

यह किसी भी तरह बाईं तरफ पंक्तियों की एक और StackPanel की व्यवस्था है, और फिर सही पैनल के पहले स्तंभ के लिए बाएं फलक के डेटा बाध्य करने के लिए सार्थक होगा? फिर आप दाएं पैनल के पहले कॉलम को छुपा सकते हैं। बाएं पैनल को क्षैतिज स्क्रॉलिंग के बिना उचित रूप से आकार दिया जा सकता है, और दाहिने पैनल में सामान्य क्षैतिज स्क्रॉलिंग होगी।

मैं बाएं पैनल के ऊर्ध्वाधर स्क्रॉल कल्पना किसी भी तरह सही पैनल की कि करने के लिए बाध्य करना होगा।

बस एक विचार; आशा है कि आप एक बेहतर तरीका पा सकते हैं।

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