यदि चयनित हो तो सूची बॉक्स आइटम के लिए WPF DataTemplate बदलें


91

मुझे सूची में आइटम के लिए DataTemplate को बदलने की आवश्यकता है, इस पर निर्भर करता है कि आइटम का चयन किया गया है या नहीं (चयनित होने पर अलग / अधिक जानकारी प्रदर्शित करता है)।

जब मैं प्रश्न में केवल सूची बॉक्स आइटम पर क्लिक करता हूं (केवल टैब के माध्यम से), और मैं विचारों से बाहर हूं, तो मुझे डेटाटेम्पलेट (एक स्टैकपैनल) में सबसे अधिक तत्व पर एक गॉटफोकस / लॉस्टफोकस घटना नहीं मिलती है और मैं विचारों से बाहर हूं।

जवाबों:


184

ऐसा करने का सबसे आसान तरीका "ItemContainerStyle" के लिए टेम्पलेट की आपूर्ति करना है और "ItemTemplate" संपत्ति नहीं है। नीचे दिए गए कोड में मैं 2 डेटा टेम्पलेट बनाता हूं: "अचयनित" के लिए एक और "चयनित" राज्यों के लिए। मैं तब "ItemContainerStyle" के लिए एक टेम्पलेट बनाता हूं जो वास्तविक "ListBoxItem" है जिसमें आइटम शामिल है। मैं डिफ़ॉल्ट "ContentTemplate" को "अचयनित" स्थिति पर सेट करता हूं, और फिर एक ट्रिगर की आपूर्ति करता हूं जो "IsSelected" संपत्ति सत्य होने पर टेम्पलेट को स्वैप करता है। (नोट: मैं "आइटम स्रोत" संपत्ति को सरलता के लिए तार की सूची के पीछे कोड में सेट कर रहा हूं)

<Window.Resources>

<DataTemplate x:Key="ItemTemplate">
    <TextBlock Text="{Binding}" Foreground="Red" />
</DataTemplate>

<DataTemplate x:Key="SelectedTemplate">
    <TextBlock Text="{Binding}" Foreground="White" />
</DataTemplate>

<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
    <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

</Window.Resources>
<ListBox x:Name="lstItems" ItemContainerStyle="{StaticResource ContainerStyle}" />

1
धन्यवाद, कृपया अपने पोस्ट में <ListBox ItemContainerStyle = "{StaticResource कंटेनerStyle}" ItemSource = "{बाइंडिंग MyData}" /> शामिल करें, ताकि लोगों को आपके ब्लॉग में खोजना न पड़े।
शिम्मी वीटहैंडलर

2
ListBox के कंटेनरसेटाइल को सेट करने में मुझे एक समस्या यह है कि यह थीम के साथ असंगति का कारण बनता है। मैंने आपके दृष्टिकोण का उपयोग किया था, लेकिन जब मैंने WPF फ्यूचर्स से एक थीम लागू की तो ListBoxItems ने थीम स्टाइल के बजाय डिफ़ॉल्ट स्टाइलिंग सेट की। मेरे मामले में, काले रंग की पृष्ठभूमि और सामान्य कुरूपता पर काला पाठ। मैं अभी भी एक और दृष्टिकोण की खोज कर रहा हूं, शायद डेटाटेम्पलेट ट्रिगर्स का उपयोग कर रहा हूं।
बेनी जोबिगन

1
इसके अलावा, यदि आप चाहते हैं कि आपका नया ItemContainerStyle थीम के साथ संगत हो, तो आपको इसे थीम से एक पर आधारित करना होगा। ऐसा करने के लिए, BasedOn="{StaticResource {x:Type ListBoxItem}}"सूची बॉक्स के साथ उपयोग करें । यह ट्रीव्यू जैसे अन्य नियंत्रणों पर भी लागू होता है।
बेनी जोबिगन

5
इसका उपयोग करते हुए मैंने पाया कि मुझे आर्कान XAMA त्रुटियों को प्राप्त नहीं करने के लिए संसाधन अनुभाग में शैली के ऊपर DataTemplates की घोषणा करनी थी। बस एक सिर-उसके बारे में।
रोब पर्किंस

8

शैली का चयन करने के लिए जब आइटम का चयन किया जाता है या नहीं, तो आपको केवल अपने परिवर्तन ListBoxItemमें माता-पिता को पुनः प्राप्त करना होगा <DataTemplate>और शैली में IsSelectedपरिवर्तन करना होगा। उदाहरण के लिए नीचे दिया गया कोड TextBlockडिफ़ॉल्ट Foregroundरंग हरा बना देगा । अब यदि आइटम चयनित हो जाता है तो फ़ॉन्ट लाल हो जाएगा और जब आइटम खत्म हो जाएगा तो माउस पीला हो जाएगा । इस तरह आपको अलग-अलग डेटा टेम्प्लेट निर्दिष्ट करने की आवश्यकता नहीं है, जैसा कि हर उस राज्य के लिए सुझाए गए हैं, जिसमें आप थोड़ा बदलाव करना चाहते हैं।

<DataTemplate x:Key="SimpleDataTemplate">
    <TextBlock Text="{Binding}">
        <TextBlock.Style>
            <Style>
                <Setter Property="TextBlock.Foreground" Value="Green"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Red"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Yellow"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</DataTemplate>

1
जैसा कि मैंने सवाल में लिखा था, मैं वास्तव में अधिक जानकारी दिखा रहा हूं यदि चयनित ("चयनित होने पर अलग / अधिक जानकारी प्रदर्शित करना ")। फिर भी, अगर यह कुछ तत्वों (जिसमें वे आकार लेते हैं सहित) की टॉगल दृश्यता के साथ काम करने के लिए बनाया जा सकता है, यह एक व्यवहार्य समाधान होगा। हालांकि थोड़ी देर में WPF के साथ काम नहीं किया गया।
डेनियल बेक

6

यह भी ध्यान दिया जाना चाहिए, कि स्टैम्पपेल फिजिबल नहीं है, इसलिए यह कभी फोकस प्राप्त करने वाला नहीं है (यदि आप वास्तव में / फोकस चाहते हैं तो फोकस करने योग्य = सच सेट करें)। हालांकि, इस तरह के परिदृश्यों में याद रखने की कुंजी यह है कि स्टैकपैनल बच्चा है है, जो इस मामले में आइटम कॉर्नर है। जैसा कि मीका सुझाव देते हैं, आइटमकॉनटेनस्टाइल को ट्विक करना एक अच्छा तरीका है।

आप शायद डेटाटेम्पलेट्स, और डेटाट्रीगर्स जैसी चीजों का उपयोग कर सकते हैं जो लिस्टव्यूमेटेम देखने के लिए RelativeSouce मार्कअप एक्सटेंशन का उपयोग करेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.