2010-02-03 5 views
6

मैं एक ListBox वर्ग के लिए एक DataTemplate जोड़ लिया है करने के लिए अपने संग्रह बाध्य करने के लिए:करें ListBoxItem अगर ItemTemplate में पाठ बॉक्स ध्यान केंद्रित हो जाता है

<ListBox x:Name="lstEmails" Height="259" Margin="12,0,12,41" Width="276" 
     SelectionChanged="lstEmails_SelectionChanged"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Label Visibility="Hidden" Content="{Binding ID}"></Label> 
       <TextBox Width="200" Text="{Binding EmailAddress}"></TextBox> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

यह ठीक करता है कि मैं क्या करना चाहते हैं। हालांकि जब मैं TextBox पर क्लिक करता हूं, ListBox स्वचालित रूप से ListItem को Selected के रूप में सेट नहीं करता है। मैं इसे कोड में कर सकता था, लेकिन मैं इसे एक घटक के रूप में उपयोग करना पसंद करूंगा (तब वहां कोई आश्चर्य नहीं)।

इसे प्राप्त करने के तरीके पर कोई विचार?


ऐसा लगता है कि यह काम नहीं कर रहा है, यह मुझे किसी भी चीज़ पर क्लिक करने नहीं देगा। क्या मुझे कुछ याद आया है। मेरा नया एक्सएएमएल यहाँ है।

<UserControl.Resources> 
    <!--<TextBox x:Key="TB" x:Name="TextBoxInsideListBoxItemTemplate"> 
     <TextBox.Style>--> 
      <Style TargetType="{x:Type TextBox}"> 
       <Setter Property="IsHitTestVisible" Value="False" /> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" 
                Value="True"> 
         <Setter Property="IsHitTestVisible" Value="True" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     <!--</TextBox.Style> 
    </TextBox>--> 
</UserControl.Resources> 
<Grid> 
    <ListBox x:Name="lstEmails" Height="259" Margin="12,0,12,41" Width="276" SelectionChanged="lstEmails_SelectionChanged"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <!--<Label Visibility="Hidden" Content="{Binding ID}"></Label>--> 
        <TextBox Width="220" Text="{Binding EmailAddress}" > 
        </TextBox> 
        <!--<TextBox Width="220" Text="{Binding EmailAddress}" GotFocus="TextBox_GotFocus"></TextBox>--> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Width="20" Margin="12,0,0,12" Name="btnAdd" VerticalAlignment="Bottom" Click="btnAdd_Click" Height="23" HorizontalAlignment="Left">+</Button> 
    <Button Width="20" HorizontalAlignment="Left" Margin="30,0,0,12" Name="btnRemove" VerticalAlignment="Bottom" Click="btnRemove_Click" Height="23">-</Button> 
    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,12,12" Name="btnApply" VerticalAlignment="Bottom" Width="49" Click="btnApply_Click">Apply</Button> 
</Grid> 

मुझे लगता है कि क्लिक दो बार थोड़ा अच्छा कार्यक्षमता है।

उत्तर

3

यदि आपके पास ListBox का एकाधिक उदाहरण है तो आप अपने कस्टम सूची बॉक्स का उपयोग करने पर विचार कर सकते हैं (इसे ListBox से प्राप्त करके)। the explanation here देखें।


या, का उपयोग इस हैक अगर आप केवल 1 (या केवल की छोटी संख्या है) इस तरह के ListBox और उस के लिए एक अलग वर्ग बनाने के लिए नहीं करना चाहती:

<TextBox x:Name="TextBoxInsideListBoxItemTemplate" ... > 

    <TextBox.Style> 
     <Style TargetType="{x:Type TextBox}"> 
      <Setter Property="IsHitTestVisible" Value="False" /> 
      <Style.Triggers> 
       <DataTrigger 
         Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" 
         Value="True"> 
        <Setter Property="IsHitTestVisible" Value="True" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBox.Style> 

</TextBox> 

ध्यान दें कि आपको TextBox (जो वास्तव में मेरे अनुसार अच्छा है) में टेक्स्ट संपादित करने के लिए एक बार फिर क्लिक करना होगा।

7

ItemContainerStyle में आप संपत्ति IsKeyboardFocusWithin पर ट्रिगर कर सकते हैं और IsSelected से true पर सेट कर सकते हैं।

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}}" Value="True"> 
       <DataTrigger.EnterActions> 
        <BeginStoryboard> 
         <Storyboard> 
          <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ListBoxItem.IsSelected)"> 
           <DiscreteBooleanKeyFrame KeyTime="0" Value="True"/> 
          </BooleanAnimationUsingKeyFrames> 
         </Storyboard> 
        </BeginStoryboard> 
       </DataTrigger.EnterActions> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</ListBox.ItemContainerStyle> 

तुम भी एक Setter बजाय एक भी फ्रेम एनीमेशन के इस्तेमाल कर सकते हैं, लेकिन फिर चयन फिर से एक बार फोकस छोड़ देता है ListBox खो जाएगा:

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}}" Value="True"> 
       <Setter Property="IsSelected" Value="True"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</ListBox.ItemContainerStyle> 
+0

शानदार! आज मुझे बचाया! –

+0

यह एक अच्छा समाधान है, सिवाय इसके कि यह विस्तारित और एकाधिक चयन मोड के साथ अच्छी तरह से जाल नहीं है। – xvpower

0

मैं एक स्थिति थी, जहां एक के चयन सूची बॉक्स आइटम अपना लेआउट बदल देगा, इसलिए माउस बटन जारी होने से पहले नियंत्रण कर्सर से दूर हो सकता है। अगर मैं सब कुछ xaml में रखना चाहता हूं तो मुझे स्टोरीबोर्ड में थोड़ी देर के विलंब का उपयोग करने से बेहतर समाधान नहीं मिला है।

अधिक महत्वपूर्ण बात यह है कि GotKeyboardFocus बार-बार चयन के लिए IsKeyboardFocusWithin से बेहतर काम करता प्रतीत होता है।

<EventTrigger RoutedEvent="GotKeyboardFocus"> 
    <BeginStoryboard> 
     <Storyboard> 
      <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected"> 
       <DiscreteBooleanKeyFrame KeyTime="00:00:00.3" Value="True"/> 
      </BooleanAnimationUsingKeyFrames> 
     </Storyboard> 
    </BeginStoryboard> 
</EventTrigger> 
संबंधित मुद्दे