2009-09-22 16 views
11

मैं एक DataTemplate कि एक टेम्प्लेट की ListBoxItem होगा चयन, इस DataTemplate कि इस टेम्पलेट चयन किया है, यह बन का प्रतिनिधित्व करता है उस में एक ComboBox जो जब यह ध्यान केंद्रित किया है मैं चाहता हूँ ListBoxItem है मुझे सही लग रहा है लेकिन दुर्भाग्य से पर्याप्त यह काम नहीं करता = (एक ListBoxItem जब इसकी भीतरी ComboBox केंद्रित है

तो यहाँ असली सवाल एक DataTemplate के भीतर है इसे पाने के लिए या एक DataTemplate.Trigger?

<DataTemplate x:Key="myDataTemplate" 
       DataType="{x:Type local:myTemplateItem}"> 

<Grid x:Name="_LayoutRoot"> 
    <ComboBox x:Name="testComboBox" /> 
</Grid> 

<DataTemplate.Triggers> 
    <Trigger Property="IsFocused" value="true" SourceName="testComboBox"> 
     <Setter Property="ListBoxItem.IsSelected" Value="true" /> 
    </Trigger> 
</DataTemplate.Triggers> 

</DataTemplate> 

<ListBox ItemTemplate="{StaticResource myDataTemplate}" /> 

उत्तर

8

मैंने पाया के माध्यम से ListBoxItem.IsSelected संपत्ति के मूल्य सेट करना संभव है आपकी समस्या का समाधान।

समस्या यह है कि जब आप अपने listboxitem पर नियंत्रण रखते हैं, और नियंत्रण क्लिक किया जाता है (पाठ को इनपुट करने या कंबोबॉक्स के मूल्य को बदलने के लिए), ListBoxItem चयनित नहीं होता है।

WPF के डिफ़ॉल्ट ListBox के जगह में इस FocusableListBox का प्रयोग करें> -

public class FocusableListBox : ListBox 
{ 
    protected override bool IsItemItsOwnContainerOverride(object item) 
    { 
     return (item is FocusableListBoxItem); 
    } 

    protected override System.Windows.DependencyObject GetContainerForItemOverride() 
    { 
     return new FocusableListBoxItem(); 
    } 
} 

:

यह काम करना चाहिए।

और यह ListBoxItem का उपयोग करें:

public class FocusableListBoxItem : ListBoxItem 
{ 
    public FocusableListBoxItem() 
    { 
     GotFocus += new RoutedEventHandler(FocusableListBoxItem_GotFocus); 
    } 


    void FocusableListBoxItem_GotFocus(object sender, RoutedEventArgs e) 
    { 
     object obj = ParentListBox.ItemContainerGenerator.ItemFromContainer(this); 
     ParentListBox.SelectedItem = obj; 
    } 

    private ListBox ParentListBox 
    { 
     get 
     { 
      return (ItemsControl.ItemsControlFromItemContainer(this) as ListBox); 
     } 
    } 

} 

एक Treeview भी इस समस्या है, लेकिन इस समाधान, एक Treeview लिए काम नहीं करता क्योंकि Treeview की SelectedItemreadonly है। तो यदि आप ट्रीव्यू के साथ मेरी मदद कर सकते हैं तो कृपया ;-)

+1

मेरी समस्या हल हो गई। मैं वास्तव में इस पर काफी स्टंप था। समाधान के लिए दिलचस्प दृष्टिकोण। एक्सएएमएल में ऐसा करने का कोई तरीका है तो मैं बहुत उत्सुक हूं? – AppleDrink

+0

कोई विचार नहीं है कि यह xaml में संभव है या नहीं। मुझे खुशी है कि यह सिर्फ कोड में काम करता है :) – Natrium

0

कोई विचार नहीं कि आपका ट्रिगर क्यों काम नहीं करता है। कॉम्बो बॉक्स (या किसी सूची बॉक्स आइटम के अंदर कोई नियंत्रण) प्राप्त करने के लिए आप संलग्न रूटेड घटनाओं का उपयोग कर सकते हैं। यदि आपको अपने आवेदन के अन्य हिस्सों में इस व्यवहार की आवश्यकता है तो आप कोड को व्युत्पन्न सूची बॉक्स में भी डाल सकते हैं।

XAML: सभी के लिए ऊपर hooking के पीछे

<Window x:Class="RoutedEventDemo.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Specialized="clr-namespace:System.Collections.Specialized;assembly=System" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    Height="300" Width="300"> 

    <Window.Resources> 

     <DataTemplate x:Key="myDataTemplate"> 
      <Grid> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding}" Margin="5,0"/> 
        <ComboBox Width="50"> 
         <ComboBoxItem>AAA</ComboBoxItem> 
         <ComboBoxItem>BBB</ComboBoxItem> 
        </ComboBox> 
       </StackPanel> 
      </Grid> 
     </DataTemplate> 

    </Window.Resources> 

    <Grid> 

     <ListBox ItemTemplate="{StaticResource myDataTemplate}"> 
      <ListBox.ItemsSource> 
       <Specialized:StringCollection> 
        <System:String>Item 1</System:String> 
        <System:String>Item 2</System:String> 
        <System:String>Item 3</System:String> 
       </Specialized:StringCollection> 
      </ListBox.ItemsSource> 
     </ListBox> 

    </Grid> 
</Window> 

कोड ध्यान केंद्रित घटनाओं मिला है।

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

namespace RoutedEventDemo 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      EventManager.RegisterClassHandler(typeof(UIElement), 
               GotFocusEvent, 
               new RoutedEventHandler(OnGotFocus)); 
     } 

     private static void OnGotFocus(object sender, RoutedEventArgs e) 
     { 
      // Check if element that got focus is contained by a listboxitem and 
      // in that case selected the listboxitem. 

      DependencyObject parent = e.OriginalSource as DependencyObject; 
      while (parent != null) 
      { 
       ListBoxItem clickedOnItem = parent as ListBoxItem; 
       if (clickedOnItem != null) 
       { 
        clickedOnItem.IsSelected = true; 
        return; 
       } 

       parent = VisualTreeHelper.GetParent(parent); 
      } 
     } 
    } 
} 
8

मैंने पाया कि मैं इस का उपयोग करने के लिए पसंद: सभी listboxitems के लिए

<Style TargetType="ListBoxItem"> 
    <Style.Triggers> 
     <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
      <Setter Property="IsSelected" Value="True"></Setter> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

सरल और काम करता है, भले ही अंदर क्या है की।

+0

हर बार जब मुझे यह समस्या मिली तो आपका उत्तर सहायक था। लेकिन अब मेरे पास ListBoxItem पर एक डिलीट बटन है जो फोकसबल = गलत है। इस मामले में जब इस बटन पर क्लिक करते समय पुराने चयनित इटैम को उस आइटम को चुनने के बजाय हटा दिया जाता है जिस पर हटाएं बटन क्लिक किया गया था और फिर इसे हटा दें। – Vishal

+1

आपका उत्तर काम करता है लेकिन बटन या किसी अन्य नियंत्रण पर क्लिक करने के बाद मेरी चयनित अनुक्रमणिका -1 पर रीसेट हो जाती है – Decoder94