将Windows窗体转换为Windows Metro窗体

时间:2017-07-19 15:47:05

标签: c# forms microsoft-metro windows-forms-designer

我用普通的Windows窗体编写了一个桌面应用程序,它运行正常。后来我试图将其转换为Metro形式,因为它具有现代外观。随着控件名称的微小变化,我使用了旧的普通形式的大部分代码。但是表单调整大小功能块抛出" System.NullReferenceException"在启动应用程序时。但在评论调整大小事件后,它工作正常。

private void Form1_Load(object sender, EventArgs e)
{
    defaultSize = this.Size;
    panel4Size = new Rectangle[] { new Rectangle(panel4.Location.X, panel4.Location.Y, panel4.Width, panel4.Height), new Rectangle(qusNo.Location.X, qusNo.Location.Y, qusNo.Width, qusNo.Height), new Rectangle(element1.Location.X, element1.Location.Y, element1.Width, element1.Height), new Rectangle(element2.Location.X, element2.Location.Y, element2.Width, element2.Height), new Rectangle(operation.Location.X, operation.Location.Y, operation.Width, operation.Height), new Rectangle(line.Location.X, line.Location.Y, line.Width, line.Height), new Rectangle(nextQus.Location.X, nextQus.Location.Y, nextQus.Width, nextQus.Height), new Rectangle(flp1.Location.X, flp1.Location.Y, flp1.Width, flp1.Height), new Rectangle(flp2.Location.X, flp2.Location.Y, flp2.Width, flp2.Height), new Rectangle(opt1.Location.X, opt1.Location.Y, opt1.Width, opt1.Height), new Rectangle(opt2.Location.X, opt2.Location.Y, opt2.Width, opt2.Height), new Rectangle(opt3.Location.X, opt3.Location.Y, opt3.Width, opt3.Height), new Rectangle(opt4.Location.X, opt4.Location.Y, opt4.Width, opt4.Height), new Rectangle(opt5.Location.X, opt5.Location.Y, opt5.Width, opt5.Height), new Rectangle(opt6.Location.X, opt6.Location.Y, opt6.Width, opt6.Height), new Rectangle(dopt1.Location.X, dopt1.Location.Y, dopt1.Width, dopt1.Height), new Rectangle(dopt2.Location.X, dopt2.Location.Y, dopt2.Width, dopt2.Height), new Rectangle(dopt3.Location.X, dopt3.Location.Y, dopt3.Width, dopt3.Height), new Rectangle(dopt4.Location.X, dopt4.Location.Y, dopt4.Width, dopt4.Height), new Rectangle(dopt5.Location.X, dopt5.Location.Y, dopt5.Width, dopt5.Height), new Rectangle(dopt6.Location.X, dopt6.Location.Y, dopt6.Width, dopt6.Height), new Rectangle(LaBackBt.Location.X, LaBackBt.Location.Y, LaBackBt.Width, LaBackBt.Height), new Rectangle(LaFinishBt.Location.X, LaFinishBt.Location.Y, LaFinishBt.Width, LaFinishBt.Height), new Rectangle(results.Location.X, results.Location.Y, results.Width, results.Height) };
    panel2Size = new Rectangle[] { new Rectangle(panel2.Location.X, panel2.Location.Y, panel2.Width, panel2.Height), new Rectangle(Easy.Location.X, Easy.Location.Y, Easy.Width, Easy.Height), new Rectangle(Hard.Location.X, Hard.Location.Y, Hard.Width, Hard.Height), new Rectangle(MdBackBt.Location.X, MdBackBt.Location.Y, MdBackBt.Width, MdBackBt.Height), new Rectangle(eelem1.Location.X, eelem1.Location.Y, eelem1.Width, eelem1.Height), new Rectangle(eelem2.Location.X, eelem2.Location.Y, eelem2.Width, eelem2.Height), new Rectangle(eelem3.Location.X, eelem3.Location.Y, eelem3.Width, eelem3.Height), new Rectangle(eelem4.Location.X, eelem4.Location.Y, eelem4.Width, eelem4.Height), new Rectangle(eelem5.Location.X, eelem5.Location.Y, eelem5.Width, eelem5.Height), new Rectangle(flp3.Location.X, flp3.Location.Y, flp3.Width, flp3.Height), new Rectangle(flp4.Location.X, flp4.Location.Y, flp4.Width, flp4.Height), new Rectangle(flp5.Location.X, flp5.Location.Y, flp5.Width, flp5.Height), new Rectangle(flp6.Location.X, flp6.Location.Y, flp6.Width, flp6.Height) };
    panel1Size = new Rectangle[] { new Rectangle(panel1.Location.X, panel1.Location.Y, panel1.Width, panel1.Height), new Rectangle(label1.Location.X, label1.Location.Y, label1.Width, label1.Height), new Rectangle(listView3.Location.X, listView3.Location.Y, listView3.Width, listView3.Height), new Rectangle(HmAdd.Location.X, HmAdd.Location.Y, HmAdd.Width, HmAdd.Height), new Rectangle(HmSub.Location.X, HmSub.Location.Y, HmSub.Width, HmSub.Height), new Rectangle(HmMul.Location.X, HmMul.Location.Y, HmMul.Width, HmMul.Height), new Rectangle(HmDiv.Location.X, HmDiv.Location.Y, HmDiv.Width, HmDiv.Height) };
}

private void reziseChildControl()
{
    Control[] controlP4 = new Control[] { panel4, qusNo, element1, element2, operation, line, nextQus, flp1, flp2, opt1, opt2, opt3, opt4, opt5, opt6, dopt1, dopt2, dopt3, dopt4, dopt5, dopt6, LaBackBt, LaFinishBt, results };
    Control[] controlP2 = new Control[] { panel2, Easy, Hard, MdBackBt, eelem1, eelem2, eelem3, eelem4, eelem5, flp3, flp4, flp5, flp6 };
    Control[] controlP1 = new Control[] { panel1, label1, listView3, HmAdd, HmSub, HmMul, HmDiv};
    for (int j = 0; j < controlP4.Length; j++)
    {
        resizeControls(panel4Size[j], controlP4[j]);
    }
    for (int j = 0; j < controlP2.Length; j++)
    {
        resizeControls(panel2Size[j], controlP2[j]);
    }
    for (int j = 0; j < controlP1.Length; j++)
    {
        resizeControls(panel1Size[j], controlP1[j]);
    }

    }
    private void Form1_Resize(object sender, EventArgs e)
    {
        reziseChildControl();
    }

    private void resizeControls(Rectangle originalContrl, Control control)
    {
        float xRatio = (float)(this.Width) / (float)(defaultSize.Width);
        float yRatio = (float)(this.Height) / (float)(defaultSize.Height);
        int newX = (int)(originalContrl.X * xRatio);
        int newY = (int)(originalContrl.Y * yRatio);
        int newWidth = (int)(originalContrl.Width * xRatio);
        int newHeight = (int)(originalContrl.Height * yRatio);
        control.Location = new Point(newX, newY);
        control.Size = new Size(newWidth, newHeight);
    }
}

更新:抛出NullReferenceException,因为Form1_Resize事件发生在Form1_Load事件之前。在更改窗口布局(通过拖动或最大化窗口大小)之前,不应调用Form1_Resize事件。但是在Form1完全加载之前,在应用程序启动时自动调整事件调用。在检查Form1属性时,我找不到相关属性,这可能是启动时调用resize事件的原因。尝试为form1布局属性选择不同的值,除了WindowState propety之外没有太多变化。即使WindowState属性的值不同,Resize事件在启动时调用。

2 个答案:

答案 0 :(得分:0)

使用调试器很容易看出什么值为null,这是创建panelize时的问题,不要将任何启动值设置为null, 请参阅构建metro风格应用程序的这些完整指南和示例

https://msdn.microsoft.com/en-us/library/windows/apps/br211380

希望有所帮助!!!

答案 1 :(得分:0)

添加了一个简单的条件语句来调整代码大小。之后它运作良好。但是无法弄明白究竟是什么导致在启动时调用form_resize事件。可能是它在地铁框架中的添加,但不确定。

由于