我希望在Tag
TextBox
内的ComboBox
IsEditable="true"
属性
我尝试过:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="TextElement.Tag" Value="MyValue" />
</Style>
以上代码似乎不起作用。
我不想要的东西:
我不想仅针对单个属性重新定义ComboBox的ControlTemplate
。
为什么我要更改Tag
内TextBox
的{{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
答案 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
ComboBox
,style
,Binding
或Trigger
中定义的 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" />