【问题标题】:Why does custom FrameworkElement not show children?为什么自定义 FrameworkElement 不显示子级?
【发布时间】:2021-06-24 13:47:36
【问题描述】:

我创建了一个程序来检查FrameworkElement 包含TextBox 的能力。

namespace MyControls
{
    public class FooButton : FrameworkElement
    {
        public FooButton()
        {
            Width = 100;
            Height = 100;
            VisualCollection = new VisualCollection(this);
            VisualCollection.Add(new TextBox() { Text = "Meows" });
        }
        protected override int VisualChildrenCount => VisualCollection.Count;
        protected override Visual GetVisualChild(int index) => VisualCollection[index];
        public VisualCollection VisualCollection { get; }
    }
}
namespace bitmap_test_example
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

这是程序的 XAML 文件:

<Window x:Class="bitmap_test_example.MainWindow"
        xmlns:MyControls = "clr-namespace:MyControls" 
        ......
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <MyControls:FooButton></MyControls:FooButton>
        <Button>yeah</Button>
    </DockPanel>
</Window>

但不幸的是程序没有显示TextBox。 (顺便说一下,我检查了视觉树,TextBox 确实包含在自定义FooButton 中)代码有什么问题?也许应该为FrameworkElement 重新定义其他方法?

【问题讨论】:

  • 您可以尝试命名 DockPanel 并将文本框添加到其子项中吗?
  • @Emanuele 我想使用FrameworkElement 的子类。在不久的将来FooButton 将包含自己的渲染逻辑
  • 使用的最低类应该是Control类:它有控制模板,可以自定义。剥离这一点将破坏 WPF 的巨大优势 - 自定义。 Related.
  • @Sinatr 最初的问题是我错过了布局逻辑。 FrameworkElement 也是定制的好选择
  • "FrameworkElement 也是自定义的好选择" - 完全不是一般的方式。

标签: c# wpf


【解决方案1】:

您应该实现自定义元素的MeasureOverrideArrangeOverride 方法。实现应该测量和安排视觉孩子,例如:

public class FooButton : FrameworkElement
{
    private readonly UIElement _child = new TextBox() { Text = "Meows" };

    public FooButton()
    {
        AddVisualChild(_child);
    }

    protected override int VisualChildrenCount => 1;

    protected override Visual GetVisualChild(int index) => index == 0 ? 
        _child : throw new ArgumentOutOfRangeException();

    protected override Size MeasureOverride(Size availableSize)
    {
        _child.Measure(availableSize);
        return _child.DesiredSize;

    }
    protected override Size ArrangeOverride(Size finalSize)
    {
        _child.Arrange(new Rect(finalSize));
        return finalSize;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多