簡體   English   中英

ItemsControl中的WPF自定義控件

[英]WPF Custom Control inside ItemsControl

我有一個自定義控件,看起來大致像這樣:

public class MyTextBlockTest : Control
{
    static MyTextBlockTest()
    {
    }

    public static readonly DependencyProperty TextProperty =
         DependencyProperty.Register("Text", typeof(string),
         typeof(MyTextBlockTest), new FrameworkPropertyMetadata(""));

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

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        FontFamily font = new FontFamily("Times New Roman");
        Typeface typeface = new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
        FormattedText ft = new FormattedText(Text,
                                             System.Globalization.CultureInfo.CurrentCulture,
                                             System.Windows.FlowDirection.LeftToRight,
                                             typeface,
                                             15.0,
                                             Brushes.Black);

        var point = this.PointToScreen(new Point(0, 0));
        drawingContext.DrawText(ft, point);            
    }
}

我試圖在ItemsControl使用此控件:

<ScrollViewer>
    <ItemsControl ItemsSource="{Binding BigList, ElementName=MainWindowView}" Margin="0,-1,0,1">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <!--<TextBlock Text="{Binding}"/>-->
                <controls:MyTextBlockTest Text="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>

如果我啟用了注釋掉的TextBlock ,則列表顯示良好; 但是,使用我的自定義控件,WPF不能將文本放置在正確的位置。 更具體地說,它似乎只是將所有元素相互疊加打印。

this.PointToScreen調用是給我一個提示的最初想法,但是我不確定(即使這this.PointToScreen ,但沒有),它是否會對ScrollViewer做出有利的響應。

我意識到我可以簡單地將這個控件基於TextBlock控件,但是我特別想將其作為較低級別的控件的基礎,作為性能實驗。 請有人指出我一種將自定義控件正確顯示在屏幕上的方法嗎?

您的最小自定義TextBlock至少還應該重寫MeasureOverride方法以返回其大小。 否則,控件的寬度和高度為零,並且ItemsControl中的所有項目都繪制在彼此的頂部。

因此,應使用FrameworkPropertyMetadataOptions.AffectsMeasure標志注冊Text屬性。

public class MyTextBlock : FrameworkElement
{
    private FormattedText formattedText;

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(
            "Text", typeof(string), typeof(MyTextBlock),
            new FrameworkPropertyMetadata(
                string.Empty,
                FrameworkPropertyMetadataOptions.AffectsMeasure,
                (o, e) => ((MyTextBlock)o).TextPropertyChanged((string)e.NewValue)));

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

    private void TextPropertyChanged(string text)
    {
        var typeface = new Typeface(
            new FontFamily("Times New Roman"),
            FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);

        formattedText = new FormattedText(
            text, CultureInfo.CurrentCulture,
            FlowDirection.LeftToRight, typeface, 15, Brushes.Black);
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        return formattedText != null
            ? new Size(formattedText.Width, formattedText.Height)
            : new Size();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        if (formattedText != null)
        {
            drawingContext.DrawText(formattedText, new Point());
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM