【问题标题】:How to active UserControl outside the wrapper?如何在包装器外激活 UserControl?
【发布时间】:2013-08-26 10:02:27
【问题描述】:

我在UserControl遇到了一个Focus相关的问题:

假设我们有一个这样的 UserControl:

<UserControl x:Class="_20130826.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <ListBox>
            <ListBoxItem>
                <TextBlock Text="text1" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="text2" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="text3" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="text4" />
            </ListBoxItem>
        </ListBox>
    </StackPanel>
</UserControl>

MainWindow.xaml 是这样的:

<Window x:Class="_20130826.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:temp="clr-namespace:_20130826"
        Title="MainWindow">
    <StackPanel>
        <Button Content="Deactive UserControl" />
        <StackPanel>
            <Button Name="Button1" Content="Active UserControl" />
            <ContentControl>
                <temp:UserControl1 />
            </ContentControl>
        </StackPanel>
    </StackPanel>
</Window>
  • 第一步:点击text1TextBlock里面UserControl,默认 背景更改为更深

  • 第二步:点击'Deactive UserControl'按钮,让text1背景 转为较轻

  • 第三步:点击“Active UserControl”按钮,然后...

我希望将text1 背景更改为更深这意味着 UserControl 已被聚焦/激活

我怎样才能做到这一点?

【问题讨论】:

  • 不确定我是否遵循此权利,但您的Button("Active UserControl") 实际上不在您的UserControl 内,那么为什么您希望 userControl 在按下按钮时获得焦点?现在这两个按钮只属于MainWindow。我在这里错过了什么吗?
  • 感谢@Viv,实际上完整的场景是这样的:我们在 ToolWindow 中有一个用户控件,我们想在用户激活 ToolWindow 时激活用户控件,现在用户控件没有效果,如果用户做到了。
  • 好的,所以您希望UserControl 在“Active UserControl”按钮被按下时获得焦点?
  • @Viv,是的,就是这样。

标签: wpf xaml user-controls


【解决方案1】:

如果您想在按下Button("Active UserControl") 时将焦点设置为UserControl,我们可以添加一个 Click 事件处理程序并将焦点分配给 UserControl。

所以说:

<Window x:Class="_20130826.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:temp="clr-namespace:_20130826"
        Title="MainWindow">
    <StackPanel>
        <Button Content="Deactive UserControl" />
        <StackPanel>
            <Button Name="Button1" Content="Active UserControl" Click="Button1_OnClick" />
            <ContentControl>
                <temp:UserControl1 x:Name="myUserControl" />
            </ContentControl>
        </StackPanel>
    </StackPanel>
</Window>

MainWindow.xaml.cs:

private void Button1_OnClick(object sender, RoutedEventArgs e) {
  FocusManager.SetFocusedElement(this, myUserControl);
}

现在,当您单击“Active UserControl”Button 时,焦点将切换到UserControl。但是,这不会为您提供ListBoxItem 上的“更深”状态,因为它仍然没有焦点。所以要排序

UserControl1.xaml.cs 添加:

protected override void OnGotFocus(RoutedEventArgs e) {
  base.OnGotFocus(e);

  if (!Equals(e.OriginalSource, this))
    return;
  TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next);
  MoveFocus(tRequest);
}

这样做是当UserControl 获得焦点时,它将焦点移动到其中的下一个元素,这将是您最初单击的元素。

您可以通过以下方式获得代码的演示:Here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2016-11-04
    • 2017-08-23
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2017-06-14
    相关资源
    最近更新 更多