首页 文章

WPF:类中的控件不会显示在Canvas上

提问于
浏览
0

问题的背景

我有一个继承自主窗口的类并实现定制的IProcessSimulator接口,因为我希望将来使用不同的类 . 目前,该类存储了Grid元素和TextBlock的定义(以及它的格式,但仅限于暂时) .

我的想法是在运行时创建此(以及任何其他未来)类的不同实例,因此我创建了一个类型为IProcessSimulator的Observable集合来存储它们 . 我有一个Canvas,我想将这些类定义的元素添加到Canvas中 .

问题

主要的问题是,无论我设置什么属性,控件都不会显示在Canvas上,实际上,Visual Studio甚至不允许我将实例添加到画布,说明Specified Visual已经是另一个Visual的子项或CompositionTarget的根,虽然我没有在其他任何地方将它添加到Canvas . 我怀疑这与我的接口类型集合有关,因为 canvasName.Children.Add() 实际上将我的元素添加到另一个集合(UIElement Collection),但我对WPF相对较新 . 以前,我试图通过我的类的构造函数分配像Width和Hight这样的属性,但我也尝试调用函数无济于事 .

相关代码片段

class ProcessWindow : MainWindow,  IProcessSimulator
{
    #region Implement: ProcessSimulator
    string content = "<Add content>";
    public string Content
    {
        get
        {
            return content;
        }

        set
        {
            content = value;
        }
    }

    string title = "<Add  Title>";
    public string Title
    {
        get
        {
            return title;
        }

        set
        {
            title = value;
        }
    }

    ProcessType type = ProcessType.Default;
    public ProcessType Type
    {
        get
        {
            return type;
        }
    }

    #endregion



    //constructor for my class
    public ProcessWindow()
    {
        SetMainGrid();
        SetTitleBlock();
    }

    public Grid windowGrid = new Grid();
    public void SetMainGrid()
    {
        //give elements some props for testing purps
        windowGrid.Name = "MainGrid";
        windowGrid.Height = 200;
        windowGrid.Width = 200;
        windowGrid.Background = Brushes.Black;
        windowGrid.Margin = new Thickness(0, 0, 0, 0);

       //this would be the place for MainCanvas.Children.Add(windowGrid)
        Canvas.SetLeft(MainCanvas, 10);
        Canvas.SetTop(MainCanvas, 10);

    }
    public TextBlock titleBlock = new TextBlock();

    public void SetTitleBlock()
    {
        //place for doing another "adding"
        Canvas.SetLeft(titleBlock, 0);
        Canvas.SetTop(titleBlock, 0);

        //give elements some props for testing purps
        //I even tried swapping the order of "Canvas-commands" and property giving
        titleBlock.Name = "TitleBlockName";
        titleBlock.Text = Title;
        titleBlock.Height = 30;
        titleBlock.Width = 30;
        titleBlock.Background = Brushes.Black;
    }

主窗口

public partial class MainWindow : Window
{
    public ObservableCollection<IProcessSimulator> ProcessElements { get; set; }


    public MainWindow()
    {
        InitializeComponent();
        ProcessElements = new ObservableCollection<IProcessSimulator>();
    }

    private void Default_Click(object sender, RoutedEventArgs e)
    {
        //acc to the simple test, the collection is addable and the elements are stored in it
        ProcessElements.Add(new ProcessWindow());
        //ProcessElements[0].Initialize();
        MessageBox.Show("Element number" + ProcessElements.Count.ToString());
    }

我确信这是我身边的一些基本错误,但我似乎无法弄明白 .

1 回答

  • 0

    我找到了问题的解决方案,所以如果有人在将来遇到同样的问题,我会在这里发布我的解决方案 .

    解决方案

    主要的问题是,正如@Clemens向我指出的那样,一个窗口不能成为主窗口的孩子(我仍然很好奇为什么,但这是另一个问题) . 由于我的自定义类继承自MainWindow,它也成为了一个Window元素 .

    但是我必须弄清楚如何在不使用Canvas的情况下向Canvas添加元素,这很简单:我将Canvas本身作为参数传递给我的类的构造函数,所以这样我可以随时调用它 . 这是稍微修改的代码,所以现在我将网格放置在创建元素时鼠标指向的任何位置:

    负责设置元素的函数

    public void SetMainGrid(Canvas canvasOnWhichElementsAreDisplayed)
        {
            windowGrid = new Grid();
            canvasOnWhichElementsAreDisplayed.Children.Add(windowGrid);
            var mousePosition = Mouse.GetPosition(canvasOnWhichElementsAreDisplayed);
            Canvas.SetLeft(windowGrid, mousePosition.X);
            Canvas.SetTop(windowGrid, mousePosition.Y);
            windowGrid.Name = "MainGrid";
            windowGrid.Height = 200;
            windowGrid.Width = 200;
            windowGrid.Background = Brushes.Black;
        }
    

    处理click事件的函数

    private void Default_Click(object sender, RoutedEventArgs e)
        {
            ProcessElements.Add(new ProcessWindow(MainCanvas));
            MessageBox.Show("Element number" + ProcessElements.Count.ToString());
        }
    

相关问题