2010-02-06 20 views
7

में SelectionBoxItem को कस्टमाइज़ करने के लिए कैसे करें मैं कॉम्बोबॉक्स में चयनित आइटम के रूप में एक कस्टम टेम्पलेट/आइटम प्रदर्शित करना चाहता हूं (यह आइटम वास्तव में आइटम्स की सूची में मौजूद नहीं है और अलग-अलग अपडेट किया गया है)। इसे एक आइटम भी होने की आवश्यकता नहीं है, केवल कस्टम व्यू प्रदान करना ही काम करेगा।WPF: कॉम्बोबॉक्स

वर्तमान कॉम्बोबॉक्स विषय में रहने के दौरान मैं यह कैसे कर सकता हूं (इसलिए कोई नियंत्रण टेम्पलेट प्रतिस्थापन संभव नहीं है)? जहां तक ​​मैं देखता हूं, SelectionBox * गुण सभी संपादन योग्य नहीं हैं और आंतरिक रूप से कॉम्बोबॉक्स अज्ञात सामग्री प्रस्तुतकर्ता का उपयोग करता है।

+0

यह आपके उपयोगकर्ताओं को भ्रमित करने के लिए चाटना है, लोगों को एक कंस्ट्रो बॉक्स को एक कंस्ट्रो बॉक्स के रूप में व्यवहार करने की उम्मीद है। –

+0

वैसे यह चेकबॉक्स के साथ एक कॉम्बोबॉक्स है जो असामान्य हो सकता है, लेकिन मैं यह नहीं कहूंगा कि यह बहुत भ्रमित (या बुराई) है। एक अतिरिक्त पॉपअप विंडो का उपयोग करना ओवरकिल की तरह लगता है, और यह तत्व पूर्ण आकार की चेकबॉक्स सूची होने के लिए पर्याप्त महत्वपूर्ण नहीं है। –

+0

स्पष्ट रूप से मैं एक चयनित आइटम नहीं दिखा सकता क्योंकि मेरे पास एक भी चयनित आइटम नहीं है। –

उत्तर

18

मैं इस तरह यह करना होगा:

<Window.Resources> 

    <DataTemplate x:Key="NormalItemTemplate" ...> 
    ... 
    </DataTemplate> 

    <DataTemplate x:Key="SelectionBoxTemplate" ...> 
    ... 
    </DataTemplate> 

    <DataTemplate x:Key="CombinedTemplate"> 
    <ContentPresenter x:Name="Presenter" 
     Content="{Binding}" 
     ContentTemplate="{StaticResource NormalItemTemplate}" /> 
    <DataTemplate.Triggers> 
     <DataTrigger 
     Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}" 
     Value="{x:Null}"> 
     <Setter TargetName="Presenter" Property="ContentTemplate" 
       Value="{StaticResource SelectionBoxTemplate}" /> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
    </DataTemplate> 

</Window.Resources> 

... 

<ComboBox 
    ItemTemplate="{StaticResource CombinedTemplate}" 
    ItemsSource="..." 
    ... /> 

कारण यह काम करता है कि सामान्य रूप से CombinedTemplate सिर्फ NormalItemTemplate का उपयोग करता है अपने डेटा पेश करने के लिए है, लेकिन अगर कोई ComboBoxItem पूर्वज यह मान लिया गया है कि यह चयन बॉक्स में है, इसलिए यह SelectionBoxTemplate का उपयोग करता है।

ध्यान दें कि तीन DataTemplatesResourceDictionary के किसी भी स्तर में शामिल किया जा सकता है (बस Window स्तर पर नहीं) या यहां तक ​​कि सीधे ComboBox भीतर, आपकी पसंद पर निर्भर करता है।

+0

धन्यवाद, मैं निश्चित रूप से यह कोशिश करूँगा। –

+0

यह एक सुरुचिपूर्ण * और * कामकाजी समाधान दोनों है, बहुत बहुत धन्यवाद! –

+2

हालांकि, यह बाध्यकारी अपवाद उत्पन्न करता है: 'संदर्भ के साथ बाध्यकारी के लिए स्रोत नहीं मिल सकता है' रिलेटिवसोर्स FindAncestor, पूर्वज टाइप = 'System.Windows.Controls.ComboBoxItem', पूर्वज एलवेल = '1'''। मुझे लगता है कि 'ItemTemplateSelector' सेटिंग एक बेहतर तरीका है। यहां एक उदाहरण दिया गया है: http://social.msdn.microsoft.com/Forums/vstudio/en-US/0467c9ca-efb2-4506-96e7-08ce3356860a/combobox-one-template-for-selected-item-one-for -the-dropdown-list? forum = wpf –

-1

आपको Triggers और Styles पर देखने की आवश्यकता है। तुम भी StackOverflow पर यहाँ मेरी बड़े सवालों में से कुछ की जांच के लिए चाहते हो सकता है कि मदद की मुझे इन समस्याओं को जीत:

+0

धन्यवाद, दुर्भाग्य से अन्य उत्तरों की तुलना में यह बहुत ही अमूर्त था। मेरे पास ट्रिगर्स कैसे काम करता है इसका एक सामान्य विचार है, यह {x: Null} समाधान था जिसे मैं आविष्कार नहीं कर सका। –

0

यदि मैं यह सीधे है, तो आप एक नियंत्रण चाहते हैं कि ड्रॉप-डाउन बटन के साथ कुछ मनमाने ढंग से प्रदर्शित किया गया है जो उनके बगल में स्थित चेकबॉक्स वाले आइटमों की एक सूची प्रदर्शित करता है?

मैं इसे प्राप्त करने के लिए ComboBox को पुन: स्थापित करने की कोशिश करने से भी परेशान नहीं होगा। समस्या यह है कि ComboBox आपको जो चाहिए उससे अलग पथ से अधिक विशिष्ट है। यदि आप ComboBox ControlTemplate Example देखते हैं, तो आप देखेंगे कि यह संभव मानों की सूची प्रदर्शित करने के लिए Popup नियंत्रण का उपयोग करता है।

आप UserControl बनाने के लिए मार्गदर्शन के रूप में उस टेम्पलेट के टुकड़े ले सकते हैं जो समझना आसान है और आप जो चाहते हैं उसे बेहतर प्रदान करते हैं। आप SelectedItems संपत्ति भी जोड़ सकते हैं और ऐसे ComboBox प्रदान नहीं करते हैं।

मार्गदर्शन से मेरा क्या मतलब है इसका एक उदाहरण: Popup में IsOpen संपत्ति है। नियंत्रण टेम्पलेट में, यह {TemplateBinding IsDropDownOpen} पर सेट है, जिसका अर्थ है कि ComboBox कक्षा में IsDropDownOpen संपत्ति है जो Popup के विस्तार/पतन को नियंत्रित करने के लिए बदली गई है।

+0

कस्टम नियंत्रण के साथ समस्या यह है कि वे अंतर्निर्मित शैलियों द्वारा स्टाइल नहीं हैं। मैंने पहले से ही चयनित इटम्स के साथ एक कस्टम नियंत्रण बनाया है, लेकिन इसके अंदर कॉम्बोबॉक्स पर निर्भर करता है क्योंकि मैं डिफ़ॉल्ट शैलियों को दोहराने के बिना इसके साथ काम करना चाहता हूं। –

0

रे बर्न्स 'answer पर एलेक्सी Mitev की टिप्पणी मुझे प्रेरित निम्नलिखित यथोचित कम उपयोगिता वर्ग है, जो अब मैं अपने सभी WPF परियोजनाओं में उपयोग लिखने के लिए: पिटारे में इसी के साथ

public class ComboBoxItemTemplateSelector : DataTemplateSelector 
{ 
    public List<DataTemplate> SelectedItemTemplates { get; } = new List<DataTemplate>(); 
    public List<DataTemplate> DropDownItemTemplates { get; } = new List<DataTemplate>(); 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     return GetVisualParent<ComboBoxItem>(container) == null 
      ? ChooseFrom(SelectedItemTemplates, item) 
      : ChooseFrom(DropDownItemTemplates, item); 
    } 

    private static DataTemplate ChooseFrom(IEnumerable<DataTemplate> templates, object item) 
    { 
     if (item == null) 
      return null; 
     var targetType = item.GetType(); 
     return templates.FirstOrDefault(t => (t.DataType as Type) == targetType); 
    } 

    private static T GetVisualParent<T>(DependencyObject child) where T : Visual 
    { 
     while (child != null && !(child is T)) 
      child = VisualTreeHelper.GetParent(child); 
     return child as T; 
    } 
} 

, यह लिखने के लिए संभव है XAML इस तरह:

<UserControl.Resources> 
    <DataTemplate x:Key="SelectedItemTemplateForInt" DataType="{x:Type system:Int32}"> 
     <!-- ... --> 
    </DataTemplate> 

    <DataTemplate x:Key="SelectedItemTemplateForDouble" DataType="{x:Type system:Double}"> 
     <!-- ... --> 
    </DataTemplate> 

    <DataTemplate x:Key="DropDownItemTemplateForInt" DataType="{x:Type system:Int32}"> 
     <!-- ... --> 
    </DataTemplate> 

    <DataTemplate x:Key="DropDownItemTemplateForDouble" DataType="{x:Type system:Double}"> 
     <!-- ... --> 
    </DataTemplate> 
</UserControl.Resources> 

<ComboBox> 
    <ComboBox.ItemTemplateSelector> 
     <local:ComboBoxItemTemplateSelector> 
      <local:ComboBoxItemTemplateSelector.SelectedItemTemplates> 
       <StaticResource ResourceKey="SelectedItemTemplateForInt" /> 
       <StaticResource ResourceKey="SelectedItemTemplateForDouble" /> 
      </local:ComboBoxItemTemplateSelector.SelectedItemTemplates> 

      <local:ComboBoxItemTemplateSelector.DropDownItemTemplates> 
       <StaticResource ResourceKey="DropDownItemTemplateForInt" /> 
       <StaticResource ResourceKey="DropDownItemTemplateForDouble" /> 
      </local:ComboBoxItemTemplateSelector.DropDownItemTemplates> 
     </local:ComboBoxItemTemplateSelector> 
    </ComboBox.ItemTemplateSelector> 
</ComboBox> 
संबंधित मुद्दे