我搜索过高低,但我无法想出这个。我正在构建一个包含可编辑项目的ListBox
。我DataTemplate
的{{1}}包含ListBox.ItemTemplate
和TextBlock
(除其他外)。 TextBox
始终可见,TextBlock
仅在用户双击TextBox
后才可见。当用户点击列表中的其他项目时,TextBlock
会再次隐藏以显示TextBox
。所有这一切都很棒。看我的代码:
XAML
TextBlock
C#
<Window.Resources>
<local:GoalCollection x:Key="goals"/>
<DataTemplate x:Key="GoalItemTemplate" DataType="local:Goal">
<Grid>
<TextBlock Text="{Binding Title}"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"
VerticalAlignment="Center"/>
<TextBox Name="EntryBox"
Text="{Binding Title}"
Visibility="Hidden"
BorderBrush="{x:Null}"
Padding="-2,0,0,0"
Panel.ZIndex="1"
Margin="-2,0,0,0"/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<ListBox Name="GoalsList"
ItemsSource="{Binding Source={StaticResource goals}}"
HorizontalContentAlignment="Stretch"
ItemTemplate="{StaticResource GoalItemTemplate}"
SelectionChanged="GoalsList_SelectionChanged" />
</Grid>
我遇到的问题是,public partial class MainWindow : Window
{
GoalCollection goals;
public MainWindow()
{
InitializeComponent();
}
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject { ... }
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
goals = (GoalCollection)Resources["goals"];
}
private void TextBlock_MouseLeftButtonDown(object sender,
MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
TextBlock tblk = sender as TextBlock;
if (tblk == null)
return;
TextBox tbx = ((Grid)tblk.Parent).FindName("EntryBox") as TextBox;
if (tbx == null)
return;
tbx.Visibility = Visibility.Visible;
Keyboard.Focus(tbx);
}
}
private void GoalsList_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
ListBoxItem lbi;
ContentPresenter cp;
DataTemplate dt;
TextBox tbx;
foreach (Goal item in e.RemovedItems)
{
lbi = (ListBoxItem)GoalsList.ItemContainerGenerator.
ContainerFromItem(item);
cp = FindVisualChild<ContentPresenter>(lbi);
dt = cp.ContentTemplate;
tbx = (TextBox)dt.FindName("EntryBox", cp);
if (tbx == null)
continue;
tbx.Visibility = Visibility.Hidden;
}
}
}
会在双击后立即将焦点转移回主机TextBox
。需要额外的(第三次)点击才能关注TextBox。
通过这一点,我发现ListBoxItem
确实得到了关注。但它会立即失去它(尝试为TextBox
事件添加处理程序并逐步执行`TextBlock_MouseLeftButtonDown()'方法)。有什么想法吗?
感谢。
答案 0 :(得分:5)
我的猜测是点击事件冒泡到ListBox,它通过选择项目来处理它。
尝试将此添加到Click事件处理程序(Keyboard.Focus(tbx);
之后)
e.Handled = true;
答案 1 :(得分:3)
如果要将焦点放在子元素上,请尝试使用FocusManager。
<DataTemplate x:Key="MyDataTemplate" DataType="ListBoxItem">
<Grid>
<WrapPanel Orientation="Horizontal"
FocusManager.FocusedElement="{Binding ElementName=tbText}">
<CheckBox IsChecked="{Binding Path=Completed}" Margin="5" />
<Button Style="{StaticResource ResourceKey=DeleteButtonTemplate}"
Margin="5" Click="btnDeleteItem_Click" />
<TextBox Name="tbText"
Text="{Binding Path=Text}"
Width="200"
TextWrapping="Wrap"
AcceptsReturn="True"
Margin="5"
Focusable="True"/>
<DatePicker Text="{Binding Path=Date}" Margin="5"/>
</WrapPanel>
</Grid>
</DataTemplate>