ComboBox的水印行为

pfi*_*rno 2 c# wpf combobox

我目前有一个combobox必然的dictionary.我要做的是在其中有一个默认项目combobox,例如"请选择一个项目...",当用户实际点击combobox选择项目时,该项目就会消失.

我在这个网站上看到过类似的问题,但似乎无法让任何解决方案适合我.我唯一的运气就是把它放在我的xaml组合框代码中:

<IsEditable="True" IsReadOnly="True" Text="Please select an item..."/>
Run Code Online (Sandbox Code Playgroud)

但这当然会改变它的外观,combobox我不希望它看起来像是可编辑的.

我的代码背后:

private Dictionary<string, string> imageTypes = new Dictionary<string, string>();

public MainWindow()
{
    InitializeComponent();
    AddImage_Types();
}

public void AddImage_Types()
{
    imageTypes.Add("*.png", Png);
    imageTypes.Add("*.jpg *.jpeg *jfif", Jpg);
}

public Dictionary<string, string> ImageTypes
{
    get
    {
        return imageTypes;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的组合框的xaml:

<ComboBox Name="imageCB"
          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=ImageTypes}"
          SelectedValuePath="Value"
          DisplayMemberPath="Key" >
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

我尝试过使用触发器和样式,就像这个答案:https://stackoverflow.com/a/16782339/2480598

我确信它很简单,但我似乎无法得到它.

注意:默认项目,我的意思是当窗口加载时,一些文本已经显示在组合框中,如"请选择项目...".当用户单击组合框以从下拉列表中选择项目时,这将消失.

Ami*_*ine 8

查看TextBox的这个示例.你可以为ComboBox做同样的事情:

水印行为

1-添加对程序集System.Windows.Interactivity的引用

2-在你的xaml中声明这个

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Run Code Online (Sandbox Code Playgroud)

3-将此类添加到项目中

public class WatermarkBehavior : Behavior<ComboBox>
{
    private WaterMarkAdorner adorner;

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(WatermarkBehavior), new PropertyMetadata("Watermark"));


    public double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FontSize.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FontSizeProperty =
        DependencyProperty.Register("FontSize", typeof(double), typeof(WatermarkBehavior), new PropertyMetadata(12.0));


    public Brush Foreground
    {
        get { return (Brush)GetValue(ForegroundProperty); }
        set { SetValue(ForegroundProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Foreground.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ForegroundProperty =
        DependencyProperty.Register("Foreground", typeof(Brush), typeof(WatermarkBehavior), new PropertyMetadata(Brushes.Black));



    public string FontFamily
    {
        get { return (string)GetValue(FontFamilyProperty); }
        set { SetValue(FontFamilyProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FontFamily.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FontFamilyProperty =
        DependencyProperty.Register("FontFamily", typeof(string), typeof(WatermarkBehavior), new PropertyMetadata("Segoe UI"));



    protected override void OnAttached()
    {
        adorner = new WaterMarkAdorner(this.AssociatedObject, this.Text, this.FontSize, this.FontFamily, this.Foreground);

        this.AssociatedObject.Loaded += this.OnLoaded;
        this.AssociatedObject.GotFocus += this.OnFocus;
        this.AssociatedObject.LostFocus += this.OnLostFocus;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        if (!this.AssociatedObject.IsFocused)
        {
            if (String.IsNullOrEmpty(this.AssociatedObject.Text))
            {
                var layer = AdornerLayer.GetAdornerLayer(this.AssociatedObject);
                layer.Add(adorner);
            }
        }
    }

    private void OnLostFocus(object sender, RoutedEventArgs e)
    {
        if (String.IsNullOrEmpty(this.AssociatedObject.Text))
        {
            try
            {
                var layer = AdornerLayer.GetAdornerLayer(this.AssociatedObject);
                layer.Add(adorner);
            }
            catch { }
        }
    }

    private void OnFocus(object sender, RoutedEventArgs e)
    {
        var layer = AdornerLayer.GetAdornerLayer(this.AssociatedObject);
        layer.Remove(adorner);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
    }

    public class WaterMarkAdorner : Adorner
    {
        private string text;
        private double fontSize;
        private string fontFamily;
        private Brush foreground;

        public WaterMarkAdorner(UIElement element, string text, double fontsize, string font, Brush foreground)
            : base(element)
        {
            this.IsHitTestVisible = false;
            this.Opacity = 0.6;
            this.text = text;
            this.fontSize = fontsize;
            this.fontFamily = font;
            this.foreground = foreground;
        }

        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            var text = new FormattedText(
                    this.text,
                    System.Globalization.CultureInfo.CurrentCulture,
                    System.Windows.FlowDirection.LeftToRight,
                    new System.Windows.Media.Typeface(fontFamily),
                    fontSize,
                    foreground);

            drawingContext.DrawText(text, new Point(3, 3));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

4-并添加您的ComboBox:

<ComboBox Width="200" IsEditable="True" IsReadOnly="True">
    <i:Interaction.Behaviors>
        <local:WatermarkBehavior Text="Please select..." />
    </i:Interaction.Behaviors>
    <ComboBoxItem>Item1</ComboBoxItem>
    <ComboBoxItem>Item2</ComboBoxItem>
    <ComboBoxItem>Item3</ComboBoxItem>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)