2010-02-03 7 views
6

ListBox 클래스에 DataTemplate 클래스를 추가하여 컬렉션을 바인드했습니다.ItemTemplate의 TextBox에 포커스가 있으면 ListBoxItem을 선택하십시오.

<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을 클릭하면 ListBoxSelected과 연결된 ListItem를 자동으로 설정하지 않습니다. 코드에서이 작업을 수행 할 수 있지만이 작업을 구성 요소로 사용하는 것이 좋습니다 (그때에는 놀라움이 없습니다).

이것을 달성하는 방법에 대한 아이디어?


작동하지 않는 것 같아서 아무 것도 클릭 할 수 없습니다. 내가 뭔가를 놓쳤는가? 여기에 새 XAML이 있습니다.

<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을 참조하십시오.


또는, 당신은 하나 (또는 ​​단지 적은 수의) 경우이 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을 트리거하고 IsSelectedtrue으로 설정할 수 있습니다.

<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

Brilliant! 오늘 나를 구 했어! –

+0

이것은 확장 및 다중 선택 모드와 잘 맞지 않는다는 점을 제외하고는 훌륭한 솔루션입니다. – xvpower

0

나는 상황이 있었다 어디의 선택 목록 상자 항목은 레이아웃을 변경하므로 마우스 버튼을 놓기 전에 컨트롤이 커서에서 벗어 났을 수 있습니다. 모든 것을 xaml에 보관하려면 Storyboard에서 약간의 지연을 사용하는 것보다 더 나은 해결책을 찾지 못했습니다.

더 중요한 것은 GotKeyboardFocus은 반복 선택에 대해 IsKeyboardFocusWithin보다 잘 작동하는 것 같습니다.

<EventTrigger RoutedEvent="GotKeyboardFocus"> 
    <BeginStoryboard> 
     <Storyboard> 
      <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected"> 
       <DiscreteBooleanKeyFrame KeyTime="00:00:00.3" Value="True"/> 
      </BooleanAnimationUsingKeyFrames> 
     </Storyboard> 
    </BeginStoryboard> 
</EventTrigger> 
관련 문제