Шаблон WPF: AdornedElement не отображается! - PullRequest
0 голосов
/ 20 апреля 2010

Я хочу добавить некоторые элементы в TextBox, используя Template с дополнительными элементами и оригинальным TextBox, вставленным в нужное место. Я пытаюсь использовать 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>  

Результат - просто зеленое поле вокруг моего текста!

Ответы [ 2 ]

1 голос
/ 20 апреля 2010

К сожалению, это не совсем так. Тем не менее, это не намного сложнее, чем это. Если вы хотите добавить зеленую рамку вокруг текстового поля, изменив шаблон элемента управления, он будет выглядеть примерно так:

<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>

Важной частью здесь является ScrollViewer с именем PART_ContentHost . TextBox ищет этого парня при применении шаблона и использует его для размещения текста, каретки и т. Д. Я думаю, что вам не хватает того, что при переопределении шаблона для элемента вы переопределяете весь контрольный шаблон. К сожалению, вы не можете просто изменить кусочки, но это правда.

Конечно, если вы хотите сохранить оригинальный внешний вид TextBox, например, чтобы он по-прежнему выглядел, как Win7 TextBox, вам нужно сделать немного больше в ControlTemplate.

Что бы это ни стоило, похоже, шаблон, который вы пытаетесь применить, сработает, если вы говорите об использовании Adorner . Это похоже на работу шаблонов проверки в WPF, но это совсем другая история.

Да, и для гораздо более простого способа изменить границу на зеленый, вы должны иметь возможность просто установить свойство BorderBrush в самом TextBox. Конечно, я действительно не знаю точно, для чего ты идешь.

- НТН Дасти

0 голосов
/ 22 апреля 2010

В итоге я создал пользовательский элемент управления на основе элемента управления 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>

...