2010-02-03 31 views
6

Tôi đã thêm một DataTemplate để một lớp ListBox để ràng buộc bộ sưu tập của tôi để:Chọn ListBoxItem nếu TextBox trong ItemTemplate được tập trung

<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> 

này thực hiện chính xác những gì tôi muốn nó làm. Mặc dù khi tôi nhấp vào số TextBox, thì ListBox không tự động đặt ListItem được liên kết là Selected. Tôi có thể làm điều này trong mã, nhưng tôi muốn sử dụng điều này như một thành phần (không có bất ngờ ở đó).

Bất kỳ ý tưởng nào về cách đạt được điều này?


Điều đó dường như không hoạt động, nó sẽ không cho phép tôi nhấp vào bất kỳ thứ gì. Tôi đã bỏ lỡ một cái gì đó. Đây là XAML mới của tôi.

<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> 

Tôi nghĩ rằng nhấp đúp hai lần là chức năng tốt.

Trả lời

3

Nếu bạn có nhiều phiên bản ListBox thì bạn có thể xem xét sử dụng hộp danh sách tùy chỉnh của mình (bằng cách lấy nó từ ListBox). Xem the explanation here.


Hoặc, sử dụng này hack nếu bạn chỉ có 1 (hoặc chỉ số ít) như ListBox và không muốn tạo ra một lớp riêng biệt cho rằng:

<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> 

Lưu ý rằng bạn sẽ phải nhấp lại một lần nữa để chỉnh sửa văn bản trong số TextBox (điều này thực sự thú vị theo tôi).

7

Bạn có thể kích hoạt trên thuộc tính IsKeyboardFocusWithin trong ItemContainerStyle và đặt IsSelected thành 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> 

Bạn cũng có thể sử dụng một Setter thay vì một hình ảnh động khung đơn nhưng sau đó lựa chọn sẽ bị mất một lần nữa một khi tập trung rời 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

Brilliant! Đã lưu tôi hôm nay! –

+0

Đây là một giải pháp tuyệt vời, ngoại trừ nó không tốt với chế độ mở rộng và nhiều lựa chọn. – xvpower

0

tôi đã có một tình huống mà việc lựa chọn một mục danh sách sẽ thay đổi bố cục của nó, do đó, điều khiển có thể đã di chuyển ra khỏi con trỏ trước khi nút chuột được nhả ra. Tôi đã tìm thấy không có giải pháp tốt hơn so với sử dụng một chút chậm trễ trong Storyboard nếu tôi muốn giữ tất cả mọi thứ trong xaml.

Quan trọng hơn, GotKeyboardFocus dường như hoạt động tốt hơn IsKeyboardFocusWithin cho các lựa chọn lặp lại.

<EventTrigger RoutedEvent="GotKeyboardFocus"> 
    <BeginStoryboard> 
     <Storyboard> 
      <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected"> 
       <DiscreteBooleanKeyFrame KeyTime="00:00:00.3" Value="True"/> 
      </BooleanAnimationUsingKeyFrames> 
     </Storyboard> 
    </BeginStoryboard> 
</EventTrigger> 
Các vấn đề liên quan