0

我有基于称为“TabIndex”的VM属性隐藏/显示的各种堆栈面板/网格。使用转换器和参数,如果 TabIndex 与参数匹配,则将可见性设置为可见,否则将其折叠。

我的问题是,当使用键盘通过控件进行选项卡时,选项卡顺序进入折叠面板控件,然后返回到可见面板控件。

问题:有没有办法防止键盘进入折叠面板?诸如设置可以启用/禁用的选项卡组之类的东西?

<StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=0}">
    Controls in here...
</StackPanel>

<StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=1}">
    Controls in here...
</StackPanel>

<StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=2}">
    Controls in here...
</StackPanel>

编辑 - 添加转换器代码。

基本转换器

/// <summary>
/// A base value converter that allows direct XAML usage
/// </summary>
/// <typeparam name="T">The type of this value converter</typeparam>
public abstract class BaseValueConverter<T> : MarkupExtension, IValueConverter
    where T : class, new()
{

    #region Private Variables

    /// <summary>
    /// A single static instance of this value converter
    /// </summary>
    private static T Coverter = null;

    #endregion

    #region Markup Extension Methods
    /// <summary>
    /// Provides a static instance of the value converter
    /// </summary>
    /// <param name="serviceProvider">The service provider</param>
    /// <returns></returns>
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Coverter ?? (Coverter = new T());
    }

    #endregion

    #region Value Converter Methods

    /// <summary>
    /// The method to convert on type to another
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);

    /// <summary>
    /// The method to convert a value back to it's source type
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public abstract object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);


    #endregion
}

值转换器

/// <summary>
/// A converter that takes in an integer and returns a <see cref="Visibility"/>
/// </summary>
public class IntegerToCollapsedVisibilityValueConverter : BaseValueConverter<IntegerToCollapsedVisibilityValueConverter>
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return int.Parse((string)parameter) == (int)value ? Visibility.Visible : Visibility.Collapsed;
    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
4

2 回答 2

0

这不是一个真正的答案,因为我没有回答这个问题,只是说这是不可重复的。我将此添加为答案,因为它太大而无法成为评论,并且需要格式化。

重复我之前的评论,如果某事是Collapsed(或什至Hidden),那么其中的任何东西都不可能获得焦点。例如,创建一个新的 Wpf 项目,并将其放入它为您提供的 Window 中:

<StackPanel>
    <StackPanel>
        <TextBox Text="Example1"/>
    </StackPanel>
    <StackPanel Visibility="Hidden">
        <TextBox Text="Example2"/>
    </StackPanel>
    <StackPanel Visibility="Collapsed">
        <TextBox Text="Example3"/>
    </StackPanel>
    <StackPanel>
        <TextBox Text="Example4"/>
    </StackPanel>
</StackPanel>

现在运行应用程序并将焦点放在 Example1 中并尝试 Tabbing。焦点将从 Example1 转到 Example4 并再次返回。它不会转到示例 2 或示例 3。

更进一步,如果我使用转换器的示例代码:

<StackPanel>
    <StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=0}">
        <TextBox Text="Example1"/>
    </StackPanel>
    <StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=1}">
        <TextBox Text="Example2"/>
    </StackPanel>
    <StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=2}">
        <TextBox Text="Example3"/>
    </StackPanel>
    <StackPanel Visibility="{Binding TabIndex, Converter={local:IntegerToCollapsedVisibilityValueConverter}, ConverterParameter=3}">
        <TextBox Text="Example4"/>
    </StackPanel>
</StackPanel>

如果我把它放入窗口的构造函数中:

DataContext = new { TabIndex = 2 };

然后当我运行它时,它只显示 ConverterParameter=2 的项目,并且制表符不会让焦点转到其他任何地方。因此,您的环境中肯定还有其他一些我没有看到的事情——您需要提供一个最小、完整且可验证的示例,以便人们进一步调查。

顺便说一句,我要提一下TabIndex 是 WPF Control上的属性名称,以防您在视图模型上使用该属性名称而没有意识到。例如,也许你不小心绑定到了那个,而不是你的视图模型上的那个。

于 2018-11-01T18:11:40.867 回答
0

我认为您正在寻找的是 IsTabStop。通过将此属性设置为 false,您可以将其从选项卡列表中删除并有效地跳过它。您可以在此处查看 Microsoft 文档:https ://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.control.istabstop?view=netframework-4.7.2

如果您已经有一些代码正在通过并禁用/隐藏元素,您可以在同一个地方添加一个 {element}.IsTabStop = true/false 。这是一个例子:

void button1_click(object sender, RoutedEventArgs e)
{
    if (true)//some flag for checking if you want to hide/disable it
    {
        panel1.IsTabStop = false;
    }
}
于 2018-10-31T20:43:06.077 回答