更改驻留在ComboBox的

时间:2016-05-31 11:26:24

标签: c# wpf xaml combobox

我希望在Tag

时更改驻留在WPF TextBox内的ComboBox IsEditable="true"属性

我尝试过:

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="TextElement.Tag" Value="MyValue" />
</Style>

以上代码似乎不起作用。

我不想要的东西:

我不想仅针对单个属性重新定义ComboBox的ControlTemplate

为什么我要更改TagTextBox的{​​{1}}而不是使用ComboBox ComboBox属性:我正在使用{ {1}}课程如下:

Tag

EnterKeyTraversal

EnterKeyTraversal.cs

public class EnterKeyTraversal
{
    public static bool GetIsEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsEnabledProperty);
    }

    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }

    static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var ue = e.OriginalSource as FrameworkElement;

        DependencyObject dep = ue;

        while (!(dep == null || dep is DataGrid))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        if (!(ue is Button || ue is ListBoxItem || dep is DataGrid))
        {
            if (e.Key == Key.Enter)
            {
                if (!(ue.Tag != null && ue.Tag.ToString() == "IgnoreEnterKeyTraversal"))
                {
                    e.Handled = true;
                    ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
            }
        }
    }

    private static void ue_Unloaded(object sender, RoutedEventArgs e)
    {
        var ue = sender as FrameworkElement;
        if (ue == null) return;

        ue.Unloaded -= ue_Unloaded;
        ue.PreviewKeyDown -= ue_PreviewKeyDown;
    }

    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),

        typeof(EnterKeyTraversal), new UIPropertyMetadata(false, IsEnabledChanged));

    static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var ue = d as FrameworkElement;
        if (ue == null) return;

        if ((bool)e.NewValue)
        {
            ue.Unloaded += ue_Unloaded;
            ue.PreviewKeyDown += ue_PreviewKeyDown;
        }
        else
        {
            ue.PreviewKeyDown -= ue_PreviewKeyDown;
        }
    }
}

在其他页面上:

MainWindow

所以,我想如果我更改<Window ....... helpers:EnterKeyTraversal.IsEnabled="True"> ........ </Window> <TextBox Tag="IgnoreEnterKeyTraversal" /> <!-- Works Fine --> <ComboBox Tag="IgnoreEnterKeyTraversal" /><!-- Not Working --> 的{​​{1}},我可以停止遍历 Enter

3 个答案:

答案 0 :(得分:0)

在EnterKeyTraversal中挖掘后,我找到了解决方案:

这是我的新EnterKeyTraversal.cs

public class EnterKeyTraversal
{
    public static bool GetIsEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsEnabledProperty);
    }

    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }

    static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var ue = e.OriginalSource as FrameworkElement;

        DependencyObject dep = ue;

        while (!(dep == null || dep is DataGrid))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        DependencyObject combo = ue;

        while (!(combo == null || combo is ComboBox))
        {
            combo = VisualTreeHelper.GetParent(combo);
        }

        if (!(ue is Button || ue is ListBoxItem || dep is DataGrid || (combo is ComboBox && ((ComboBox)combo).Tag.ToString() == "IgnoreEnterKeyTraversal")))
        {
            if (e.Key == Key.Enter)
            {
                if (!(ue.Tag != null && ue.Tag.ToString() == "IgnoreEnterKeyTraversal"))
                {
                    e.Handled = true;
                    ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
            }
        }
    }

    private static void ue_Unloaded(object sender, RoutedEventArgs e)
    {
        var ue = sender as FrameworkElement;
        if (ue == null) return;

        ue.Unloaded -= ue_Unloaded;
        ue.PreviewKeyDown -= ue_PreviewKeyDown;
    }

    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),

        typeof(EnterKeyTraversal), new UIPropertyMetadata(false, IsEnabledChanged));

    static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var ue = d as FrameworkElement;
        if (ue == null) return;

        if ((bool)e.NewValue)
        {
            ue.Unloaded += ue_Unloaded;
            ue.PreviewKeyDown += ue_PreviewKeyDown;
        }
        else
        {
            ue.PreviewKeyDown -= ue_PreviewKeyDown;
        }
    }
}

答案 1 :(得分:0)

我正在回答您的初始问题:我想更改位于WPF ComboBox内的TextBox的Tag属性,当IsEditable =“true”

由于您尝试更新control's ControlTemplate ComboBoxstyleBindingTrigger中定义的 public class ComboBoxBehave { public static string GetApplyTag(DependencyObject obj) { return (string)obj.GetValue(ApplyTagProperty); } public static void SetApplyTag(DependencyObject obj, string value) { obj.SetValue(ApplyTagProperty, value); } // Using a DependencyProperty as the backing store for ApplyTag. This enables animation, styling, binding, etc... public static readonly DependencyProperty ApplyTagProperty = DependencyProperty.RegisterAttached("ApplyTag", typeof(string), typeof(ComboBoxBehave), new UIPropertyMetadata(null, ApplyTagChanged)); private static void ApplyTagChanged(DependencyObject DO, DependencyPropertyChangedEventArgs e) { var combo = DO as ComboBox; if (combo != null) { combo.Loaded += new RoutedEventHandler(combo_Loaded); } } static void combo_Loaded(object sender, RoutedEventArgs e) { var combo = sender as ComboBox; if (combo != null) { var text = FindChild<TextBox>(sender as DependencyObject, "PART_EditableTextBox"); if (text != null) { text.Tag = GetApplyTag(combo); } } } public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject { // Confirm parent and childName are valid. if (parent == null) return null; T foundChild = null; int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(parent, i); // If the child is not of the request child type child T childType = child as T; if (childType == null) { // recursively drill down the tree foundChild = FindChild<T>(child, childName); // If the child is found, break so we do not overwrite the found child. if (foundChild != null) break; } else if (!string.IsNullOrEmpty(childName)) { var frameworkElement = child as FrameworkElement; // If the child's name is set for search if (frameworkElement != null && frameworkElement.Name == childName) { // if the child's name is of the request name foundChild = (T)child; break; } } else { // child element found. foundChild = (T)child; break; } } return foundChild; } } 属性不会起作用。所以我使用了这个助手类:

助手类:

 <ComboBox Width="200" Name="cmbBox1" IsEditable="True"  >
        <ComboBox.Style>
            <Style TargetType="ComboBox">
                <Style.Triggers>
                    <Trigger Property="IsEditable" Value="True">
                        <Setter Property="local:ComboBoxBehave.ApplyTag" Value="IgnoreEnterKeyTraversal"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ComboBox.Style>
    </ComboBox>

<强> XAML:

TextBox's

并且IgnoreEnterKeyTraversal标记设置为sqlselectstring = "Select dp.PartNumber, count (fqp.fk_spQuoteID) as [# Times Quoted],count( fop.fk_spOrderId) as [# Times Ordered] " & _ "From ((DimProduct As dp LEFT JOIN FactOrderProduct AS fop ON dp.PartNumber=fop.PartNumber) LEFT JOIN FactQuoteProduct as fqp on dp.PartNumber=fqp.PartNumber) " & _ "Group By dp.PartNumber;" ,使用更多通用代码,同一个类可以与不同的控件一起使用。

答案 2 :(得分:0)

您可以考虑创建自己的ComboBox,如下所示:

public class ComboBox : System.Windows.Controls.ComboBox
{
    public static readonly DependencyProperty TextBoxTagProperty =
        DependencyProperty.Register("TextBoxTag", typeof(object), typeof(ComboBox), new UIPropertyMetadata(null, new PropertyChangedCallback(OnTextBoxTagChanged)));

    public object TextBoxTag
    {
        get { return (object)GetValue(TextBoxTagProperty); }
        set { SetValue(TextBoxTagProperty, value); }
    }


    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        FrameworkElement frameworkElement = GetTemplateChild("PART_EditableTextBox") as FrameworkElement;
        frameworkElement.Tag = TextBoxTag;
    }

    private static void OnTextBoxTagChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        ComboBox comboBox = d as ComboBox;
        FrameworkElement frameworkElement = comboBox.GetTemplateChild("PART_EditableTextBox") as FrameworkElement;
        frameworkElement.Tag = args.NewValue;
    }
}

然后在你的XAML中:

<local:ComboBox IsEditable="True" Tag="combobox tag" TextBoxTag="edit textbox tag" />