RichTextBox Пользовательский элемент управления - PullRequest
0 голосов
/ 13 сентября 2011

Я пытаюсь создать новый пользовательский элемент управления, который наследуется от RichTextBox.Причина этого заключается в том, чтобы добавить пользовательскую буферизацию в элемент управления (например, добавлять текст каждые x миллисекунд и / или buffer.Length> x).

Мне удалось создать элемент управления и добавить его в xamlОкно, , однако, похоже, что оно на самом деле не работает как RichTextBox должным образом - текст не отображается после добавления, и курсор не меняет значок при наведении курсора на элемент управления .

* 1006.* Кажется, это довольно простой код, поэтому я не уверен, в чем я ошибаюсь.

CBufferedTextBox.cs:

public class CBufferedTextBox : RichTextBox
{
    const int MAX_LENGTH = 2048;
    const int TIMER_LENGTH = 1000;

    DispatcherTimer m_timer = new DispatcherTimer();

    DispatcherTimer Timer
    {
        get { return m_timer; }
    }

    StringBuilder m_currentText = new StringBuilder();

    StringBuilder CurrentText
    {
        get { return m_currentText; }
    }


    static CBufferedTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata( typeof( CBufferedTextBox ), new FrameworkPropertyMetadata( typeof( CBufferedTextBox ) ) );
    }


    public CBufferedTextBox()
    {
        Loaded += CBufferedTextBox_Loaded;
    }

    public CBufferedTextBox( FlowDocument document )
        : base( document )
    {
    }


    public new void AppendText( string strText )
    {
        CurrentText.Append( strText );

        if( !strText.EndsWith( Environment.NewLine ) )
        {
            CurrentText.AppendLine();
        }

        if( CurrentText.Length > MAX_LENGTH )
        {
            Flush();
        }
    }

    void CBufferedTextBox_Loaded( object sender, RoutedEventArgs e )
    {
        Timer.Interval = new TimeSpan( TIMER_LENGTH );
        Timer.Tick += new EventHandler( Timer_Tick );
        Timer.Start();
    }

    void Timer_Tick( object sender, EventArgs e )
    {
        Flush();
    }

    void Flush()
    {
        Timer.Stop();
        this.BeginInvokeIfRequired( o =>
        {
            if( CurrentText.Length > 0 )
            {
                base.AppendText( CurrentText.ToString() );

                // Clear
                CurrentText.Remove( 0, CurrentText.Length );

                ScrollToEnd();
            }

            Timer.Start();
        } );
    }
}

Generic.xaml:

<Style TargetType="{x:Type local:CBufferedTextBox}" BasedOn="{StaticResource {x:Type RichTextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CBufferedTextBox}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Спасибо, Рич

1 Ответ

2 голосов
/ 13 сентября 2011

Ну, конечно, нет, вы полностью изменили Стиль и особенно ControlTemplate. Ваш контроль состоит только из границы, вот и все. Нет ввода текста, нет отображения текста нет ничего. Вам нужно реализовать хотя бы самые простые основы в своем шаблоне, чтобы позволить вашему CBufferedTextBox вести себя так, как вы ожидаете.

Я также хочу отметить, что ваш new void AppendText довольно опасен и может не выполнять то, что вы ожидаете. В вашем методе Flush вы вызываете AppendText поля RichtText, а не ваш. Также новый не то же самое, что переопределить. RichTextBox никогда не вызовет ваш метод внутри, даже если он вашего нового типа CBufferedTextBox.

...