0

我想通过使用带有额外元素的模板和插入正确位置的原始文本框来向文本框添加一些元素。我正在尝试使用 AdornedElementPlaceholder,就像您在制作 Validation.ErrorTemplate 时所做的那样,但 AdornedElement 没有出现。我已经尽可能地简化了这个例子:

<TextBox Text="Border me with my Template">
     <TextBox.Template>
      <ControlTemplate TargetType="{x:Type TextBox}">
       <Border BorderBrush="Green" BorderThickness="1">
        <AdornedElementPlaceholder/>
       </Border>
      </ControlTemplate>
     </TextBox.Template>
    </TextBox>  

结果只是在应该是我的文本框的空间周围出现了一个绿色框!

4

2 回答 2

1

不幸的是,这不是它的工作方式。然而,这并不比这更困难。如果您想通过更改控件模板在文本框周围添加绿色边框,它看起来更像这样:

<ControlTemplate TargetType="TextBox">
    <Border x:Name="Border"
            CornerRadius="2"
            Background="{TemplateBinding Background}"
            BorderBrush="Green"
            BorderThickness="1"
            SnapsToDevicePixels="True">
        <ScrollViewer x:Name="PART_ContentHost"/>
    </Border>
</ControlTemplate>

其中的重要部分是名为PART_ContentHost的 ScrollViewer 。TextBox 在应用模板时寻找那个人,并使用它来承载文本、插入符号等。我认为您缺少的是,当您覆盖元素的模板时,您将覆盖整个控件模板。不幸的是,你不能只是改变点点滴滴,但这就是事实。

当然,如果你想保持 TextBox 的原始外观和感觉,例如它仍然看起来像 Win7 TextBox,你需要在 ControlTemplate 中做更多的事情。

对于它的价值,如果您正在谈论使用Adorner ,您尝试应用的模板似乎会起作用。它类似于 WPF 中验证模板的工作方式,但这是另一回事。

哦,对于将边框更改为绿色的更简单的方法,您应该能够只在 TextBox 本身上设置 BorderBrush 属性。当然,我真的不知道你到底想要什么。

-- HTH 尘土飞扬

于 2010-04-20T13:12:24.677 回答
0

我最终做了一个基于 HeaderedContent 控件的自定义控件。

它将允许用户单击或悬停在某些内容上,然后显示包含其他或相同内容的气泡。

用法:

<JsCustomControls:BaloonBox LabelText="{Binding Note}" WaterMark="Click to write Note" Type="ClickToShow">
<JsCustomControls:BaloonBox.Content>
<TextBox AcceptsReturn="True" Text="{Binding Path=Note}" TextWrapping="Wrap"></TextBox>
</JsCustomControls:BaloonBox.Content>
</JsCustomControls:BaloonBox>

用户控件的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace JsCustomControls
{
    public enum BaloonBoxTypeEnum
    {
        ClickToShow,
        MouseOverToShow,
        Manual
    }

    [TemplatePart(Name = BaloonBox.HeaderElement, Type = typeof(ContentPresenter))]
    [TemplatePart(Name = BaloonBox.ContentElement, Type = typeof(ContentPresenter))]
    [TemplatePart(Name = BaloonBox.PopUpElement, Type = typeof(Popup))]
    [TemplatePart(Name=BaloonBox.LabelElement,Type=typeof(Label))]
    public class BaloonBox : HeaderedContentControl
    {
        DispatcherTimer PopupTimer = new DispatcherTimer();

        private const string HeaderElement = "PART_HeaderContentControl";
        private const string ContentElement = "PART_ContenContentControl";
        private const string PopUpElement = "PART_PopUp";
        private const string LabelElement = "PART_HeaderLabel";

        private ContentPresenter headerContentControl;
        private ContentPresenter contentContentControl;
        private Popup popUp;
        private Label headerLabel;

        static BaloonBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BaloonBox), new FrameworkPropertyMetadata(typeof(BaloonBox))); 
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            headerContentControl = GetTemplateChild(HeaderElement) as ContentPresenter;
            contentContentControl = GetTemplateChild(ContentElement) as ContentPresenter;
            popUp = GetTemplateChild(PopUpElement) as Popup;
            headerLabel = GetTemplateChild(LabelElement) as Label;
            if (headerContentControl != null) headerContentControl.MouseDown += new MouseButtonEventHandler(headerContentControl_MouseDown);
            if(headerLabel!=null)headerLabel.MouseDown+=new MouseButtonEventHandler(headerContentControl_MouseDown);
            if (headerContentControl != null) headerContentControl.MouseMove += new MouseEventHandler(headerContentControl_MouseMove);
            if(headerLabel!=null)headerLabel.MouseMove+=new MouseEventHandler(headerContentControl_MouseMove);
            PopupTimer = new DispatcherTimer();
            PopupTimer.Tick += new EventHandler(PopupTimer_Tick);
            if(string.IsNullOrEmpty(LabelText))
            {
                if (headerLabel != null) headerLabel.Foreground = Brushes.Gray;
                if (headerLabel != null) headerLabel.Content = WaterMark;
            }
            else
            {
                if (headerLabel != null) headerLabel.Foreground = Brushes.Black;
                if (headerLabel != null) headerLabel.Content = LabelText;
            }
        }

        void headerContentControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (Type == BaloonBoxTypeEnum.MouseOverToShow)
            {
                if (popUp != null) popUp.IsOpen = true;
                PopupTimer.Interval = new TimeSpan(0, 0, 0, 2);
                PopupTimer.Start();
            }
        }
        void headerContentControl_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (Type == BaloonBoxTypeEnum.ClickToShow)
            {
                if (popUp != null) popUp.IsOpen = true;
                PopupTimer.Interval = new TimeSpan(0, 0, 0, 3);
                PopupTimer.Start();
            }

        }
        void PopupTimer_Tick(object sender, EventArgs e)
        {
            if (!headerContentControl.IsMouseOver && !contentContentControl.IsMouseOver && !contentContentControl.IsKeyboardFocusWithin)
            {
                PopupTimer.Stop();
                popUp.IsOpen = false;
            }
        }

        public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen",
                                                                                               typeof (bool),
                                                                                               typeof (BaloonBox),
                                                                                               new FrameworkPropertyMetadata
                                                                                                   (new PropertyChangedCallback
                                                                                                        (OnIsOpenChanged)));
        public bool IsOpen
        {
            get { return (bool) GetValue(IsOpenProperty); }
            set{SetValue(IsOpenProperty,value);}
        }

        private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BaloonBox baloonBox = (BaloonBox)d;
            baloonBox.popUp.IsOpen =(bool)e.NewValue;          
        }

        public static readonly DependencyProperty WaterMarkProperty = DependencyProperty.Register("WaterMark",
                                                                                                  typeof (string),
                                                                                                  typeof (BaloonBox),
                                                                                                  new FrameworkPropertyMetadata
                                                                                                      (new PropertyChangedCallback
                                                                                                           (OnWatermarkChanged)));


        public string WaterMark
        {
            get { return (string)GetValue(WaterMarkProperty); }
            set { SetValue(WaterMarkProperty,value); }
        }

        private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText",
                                                                                                  typeof (string),
                                                                                                  typeof (BaloonBox)
                                                                                                  ,new FrameworkPropertyMetadata(new PropertyChangedCallback(OnLabelTextChanged)));

        public string LabelText
        {
            get { return (string) GetValue(LabelTextProperty); }
            set
            {
                SetValue(LabelTextProperty,value);
                headerLabel.Content = value;
            }
        }
        private static void OnLabelTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BaloonBox baloonBox = (BaloonBox)d;
            if (string.IsNullOrEmpty(e.NewValue.ToString()))
            {
                if (baloonBox.headerLabel != null) baloonBox.headerLabel.Foreground = Brushes.Gray;
                if (baloonBox.headerLabel != null) baloonBox.headerLabel.Content = baloonBox.WaterMark;
            }
            else
            {
                if (baloonBox.headerLabel != null) baloonBox.headerLabel.Foreground = Brushes.Black;
                if (baloonBox.headerLabel != null) baloonBox.headerLabel.Content = e.NewValue;
            }


        }
        public static readonly DependencyProperty BaloonBoxTypeProperty = DependencyProperty.Register(
            "BaloonBoxType", typeof(BaloonBoxTypeEnum), typeof(BaloonBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnBaloonBoxTypeChanged)));

        public BaloonBoxTypeEnum Type
        {
            get { return (BaloonBoxTypeEnum) GetValue(BaloonBoxTypeProperty);}
            set { SetValue(BaloonBoxTypeProperty,value);}
        }

        private static void OnBaloonBoxTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //who cares? 
        }
    }
}


                    </Border>
                    <Popup x:Name="PART_PopUp" HorizontalOffset="-50" VerticalOffset="-5" AllowsTransparency="True" IsOpen="False" PopupAnimation="Slide" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Header}">
                        <Grid Height="150" Width="250" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="2"></ColumnDefinition>
                                <ColumnDefinition Width="0.050*"></ColumnDefinition>
                                <ColumnDefinition Width="0.900*"></ColumnDefinition>
                                <ColumnDefinition Width="0.050*"></ColumnDefinition>
                                <ColumnDefinition Width="2"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="2"></RowDefinition>
                                <RowDefinition Height="0.300*"></RowDefinition>
                                <RowDefinition Height="0.700*"></RowDefinition>
                                <RowDefinition Height="0.100*"></RowDefinition>
                                <RowDefinition Height="2"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Path Grid.Row="1" Grid.RowSpan="3" Grid.Column="1" Grid.ColumnSpan="3" Data="M79,279 L119,279 135,263 135,279 319,279 319,368.5 78.5,368.5 z" Fill="#FFFDFDB3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False">
                            </Path>
                            <ScrollViewer Grid.Row="2" Grid.Column="2" Grid.RowSpan="1" HorizontalScrollBarVisibility="Auto"  VerticalScrollBarVisibility="Auto">
                                <ContentPresenter x:Name="PART_ContenContentControl" Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/>
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

于 2010-04-22T10:17:43.850 回答