【问题标题】:WPF Focus on the ListBox Item with control TemplateWPF 关注带有控件模板的 ListBox 项
【发布时间】:2011-07-31 09:50:48
【问题描述】:

我有一个列表框,其中包含作为文本框和按钮 (Add) 的项目模板。每当单击按钮时,都会添加一个项目(文本框)。单击按钮后,我想将焦点放在第一个文本框或最近添加的文本框上。我怎么能在 WPF 中做到这一点。如果可能从 MVVM 以可测试的方式结束

【问题讨论】:

  • 你能把相关的xaml代码贴在这里吗?用你的代码很容易弄清楚..

标签: wpf mvvm wpf-controls


【解决方案1】:

我会这样做:

  1. 在您的 VM 中,有一个 ObservableCollection 与项目。
  2. 在您的 VM 中,有一个属性 SelectedItem
  3. 在您的 VM 中,有一个命令 AddItem
  4. 将按钮连接到命令AddItem
  5. ComboBoxSelectedItem 绑定到VM 的SelectedItem
  6. AddItem 命令中,将项目添加到ObservableCollection 并将其分配给VM 的SelectedItem
  7. 在您的 DataTemplate 中,确保 TextBox 在选择项目时获得焦点。

要实现最后一点,您可以创建一个附加属性,该属性在 getter 中返回 IsFocused,并在 setter 中调用 Focus。然后,您可以将此属性附加到文本框并将其绑定到项目中的 IsFocused 属性。

【讨论】:

    【解决方案2】:

    我完全同意丹尼尔的回答,但让我用一些代码来澄清这个想法。

    首先让我们定义对“真”值做出反应的附加行为,并为其所有者设置焦点。

    public static class FocusBehaviour
    {
        public static bool GetForceFocus(DependencyObject d)
        {
            return (bool)d.GetValue(FocusBehaviour.ForceFocusProperty);
        }
    
        public static void SetForceFocus(DependencyObject d, bool val)
        {
            d.SetValue(FocusBehaviour.ForceFocusProperty, val);
        }
    
        public static readonly DependencyProperty ForceFocusProperty = 
            DependencyProperty.RegisterAttached("ForceFocus", 
                typeof(bool), 
                typeof(FocusBehaviour), 
                new FrameworkPropertyMetadata(false, 
                    FrameworkPropertyMetadataOptions.None, 
                    (d, e) => 
                        {
                            if((bool)e.NewValue)
                            {
                                if (d is UIElement)
                                {
                                    ((UIElement)d).Focus();
                                }
                            }
                        }));
    }
    

    然后将此行为添加到我们的 TextBox 中:

    <DataTemplate>
         <TextBox self:FocusBehaviour.ForceFocus="{Binding IsFocused}"/>
    </DataTemplate>
    

    当然,您应该将 IsFocused 属性添加到您的项目类:

    public class Item : ObservableObject
    {
        //...
        private bool _isFocused = true;
        public bool IsFocused
        {
            get
            {
                return this._isFocused;
            }
            set
            {
                this._isFocused = value;
                this.OnPropertyChanged("IsFocused");
            }
        }
    }
    

    在代码中的某个地方,您应该使用 IsFocused 属性为您的项目进行操作。 例如,当您添加新项目时,您应该为所有项目重置 IsFocused,除了新手。初始化集合时,应该只为第一项设置 IsFocused。

    【讨论】:

    • 这对我很有帮助,但我必须添加一个 while 循环才能使用 VisualTreeHelper 向上遍历可视化树,以找到具有 Focusable == true 的第一个父级
    猜你喜欢
    • 2018-10-14
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多