询问者
带水印可输入的ComboBox控件,还请Bob指点下!

问题
-
我想做一个带水印可输入的ComboBox模版控件,一下是我的控件模版部分代码,HintComboBox继承于ComboBox,我想点击PickButton把模版上的其他控件都隐藏掉,然后调用IsDropDownOpen 显示ComboBox自带的下拉框,但是却显示不了!请问如何显示,顺带问下有哪些比较好的学习自定义模版控件的资料!初学!
<Style TargetType="local:HintComboBox"> <Setter Property="Foreground" Value="{StaticResource ComboBoxForegroundThemeBrush}" /> <Setter Property="Background" Value="{StaticResource ComboBoxBackgroundThemeBrush}" /> <Setter Property="BorderBrush" Value="{StaticResource ComboBoxBorderThemeBrush}" /> <Setter Property="BorderThickness" Value="{StaticResource ComboBoxBorderThemeThickness}" /> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" /> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:HintComboBox"> <Grid> <Grid.Resources> <Style x:Name="SelButtonStyle" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="PointerOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverBorderThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedBorderThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement" /> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement" /> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border x:Name="BorderElement" BorderBrush="{StaticResource TextBoxButtonBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}" /> <Border x:Name="BackgroundElement" Background="{StaticResource TextBoxButtonBackgroundThemeBrush}" Margin="{TemplateBinding BorderThickness}"> <TextBlock x:Name="GlyphElement" Foreground="{StaticResource TextBoxButtonForegroundThemeBrush}" FontFamily="{StaticResource SymbolThemeFontFamily}" HorizontalAlignment="Center" Text="" VerticalAlignment="Center" /> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="WatermarkStates"> <VisualState x:Name="WatermarkVisible"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="HintTextBlock"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="InTextBox"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="TextBoxVisible"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="HintTextBlock"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="InTextBox"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="WatermarkHidden" > <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="HintTextBlock"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="InTextBox"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PickButton"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}" > </Border> <TextBox x:Name="InTextBox" Text="{TemplateBinding Text}" IsHitTestVisible="False" Visibility="Collapsed" /> <TextBlock x:Name="HintTextBlock" Text="{TemplateBinding HintText}" IsHitTestVisible="False" Visibility="Collapsed" /> <Button x:Name="PickButton" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" Style="{StaticResource SelButtonStyle}" Visibility="Visible" VerticalAlignment="Stretch" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
全部回复
-
Hi,
你的这个PickButton里面的Click事件从这里看应该是没有实现啊,这样你怎么能达到效果呢?你需要自己添加Click事件然后在处理过长中如果使用的是VisualState来管理的这些状态就是用VisualStateManager的GoToState方法去调用这个VisualState。
GoToState method:
Aaron Xue [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
public sealed class HintComboBox : ComboBox { #region Consts private const string WatermarkStatesGroupName = "WatermarkStates"; private const string WatermarkVisibleStateName = "WatermarkVisible"; private const string TextBoxVisibleStateName = "TextBoxVisible"; private const string WatermarkHiddenStateName = "WatermarkHidden"; private const string EditTextBoxName = "InTextBox"; private const string ComboBoxName = "InComboBox"; private const string WatermarkTextBlockName = "HintTextBlock"; private const string PickButtonName = "PickButton"; // private const string WatermarkBlockStyleName = "WatermarkBlockStyle"; private const string TextBoxStyleName = "TextBoxStyle"; #endregion #region 属性 /// <summary> /// 可编辑 /// </summary> public Boolean IsEditable = true; /// <summary> /// 可编辑输入 Text /// </summary> public string Text { get { return GetValue(TextProperty) as string; } set { SetValue(TextProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof(string), typeof(HintComboBox), new PropertyMetadata(string.Empty)); /// <summary> /// 水印 /// </summary> public String HintText { get { return base.GetValue(HintProperty) as String; } set { base.SetValue(HintProperty, value); } } public static readonly DependencyProperty HintProperty = DependencyProperty.Register("HintText", typeof(String), typeof(HintComboBox), new PropertyMetadata("Type something...") ); #endregion #region 新加可操作子控件 private Button PickButton; private TextBox EditBox; #endregion /// <summary> /// 构造 /// </summary> public HintComboBox() { this.DefaultStyleKey = typeof(HintComboBox); } protected override void OnApplyTemplate() { base.OnApplyTemplate(); PickButton = GetTemplateChild(PickButtonName) as Button; if (PickButton != null) { PickButton.Click += OnPickButtonClick; } EditBox = GetTemplateChild(EditTextBoxName) as TextBox; if (EditBox!=null) { EditBox.GotFocus += OnBoxGotFocus; EditBox.LostFocus += OnBoxLostFocus; EditBox.TextChanged += OnEditBoxTextChanged; } UpdateTextBoxVisualState(false, IsEditable); } #region Popup Event private void OnPickButtonClick(object sender, RoutedEventArgs routedEventArgs) { UpdateTextBoxVisualState(false, false); IsDropDownOpen = !IsDropDownOpen; } protected override void OnDropDownOpened(object e) { base.OnDropDownOpened(e); //State Change // UpdateVisualState(false, IsEditable); } protected override void OnDropDownClosed(object e) { base.OnDropDownClosed(e); // UpdateVisualState(true, IsEditable); } #endregion #region 焦点 Event protected void OnEditBoxTextChanged(object sender, TextChangedEventArgs e) { TextBox pEditBox = sender as TextBox; this.Text = pEditBox.Text; } protected void OnBoxGotFocus(object sender,RoutedEventArgs e) { // UpdateVisualState(true, IsEditable); } protected void OnBoxLostFocus(object sender, RoutedEventArgs e) { this.Text = EditBox.Text; UpdateTextBoxVisualState(false, IsEditable); } protected override void OnGotFocus(RoutedEventArgs e) { // base.OnGotFocus(e); UpdateTextBoxVisualState(true, IsEditable); bool b = EditBox.Focus(FocusState.Programmatic); } protected override void OnLostFocus(RoutedEventArgs e) { base.OnLostFocus(e); //UpdateVisualState(false, IsEditable); } #endregion #region VisualState Event /// <summary> /// /// </summary> /// <param name="isFocused">焦点</param> /// <param name="isShow">是否显示输入项与水印</param> private void UpdateTextBoxVisualState(bool isFocused, bool isShow = true) { if (!isShow) { VisualStateManager.GoToState(this, WatermarkHiddenStateName, true); return; } if (!isFocused && string.IsNullOrEmpty(this.Text)) { VisualStateManager.GoToState(this, WatermarkVisibleStateName, true); } else { VisualStateManager.GoToState(this, TextBoxVisibleStateName, true); // bool b = EditBox.Focus(FocusState.Programmatic); return; } } #endregion }
以上是我的逻辑处理代码,运行了没什么效果,还请指点下,还有就是哪里有比较好的自定义模版类的教程什么的! -
Hi,
你的这个PickButton里面的Click事件从这里看应该是没有实现啊,这样你怎么能达到效果呢?你需要自己添加Click事件然后在处理过长中如果使用的是VisualState来管理的这些状态就是用VisualStateManager的GoToState方法去调用这个VisualState。
GoToState method:
Aaron Xue [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
运行后没什么效果,初学,都是依样画葫芦,还请指点下哪里又比较全的自定义模版控件的教材! -
因为商店应用和WinRT都是全新的技术,至今没发现什么非常详细的靠谱的教材。关于自定义模版有两个博客
官方Win8博客以及Tim Heuer的博客,不过感觉都不算太详细
http://timheuer.com/blog/archive/2012/03/07/creating-custom-controls-for-metro-style-apps.aspx
最终可能很多要靠自己去试吧。
Aaron Xue [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.