2010-12-13 54 views
8

Về cơ bản tôi gặp hai vấn đề với C# .NET MDI. Bạn có thể tải về giải pháp VS2010 tái tạo lỗi here.Lỗi C# .NET MDI khi ẩn theo chương trình và hiển thị lại biểu mẫu con tối đa và khi tối đa, biểu tượng biểu mẫu con không thể thay đổi

1) Khi lập trình ẩn và hiển thị lại biểu mẫu con tối đa, nó không được tối đa hóa đúng cách một lần nữa và trở thành không được tối đa hóa hoặc ở trạng thái bình thường.

childForm = new Form(); 
childForm.Text = "Child Form"; 
childForm.MdiParent = this; 

... 

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = true; 
} 

... 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = false; 
} 

Khi hình thức con là tối đa, sau đó programicaly ẩn và hiển thị một lần nữa, nó trở thành một cái gì đó như thế này (xin chú ý đến thanh menu - hộp điều khiển biểu mẫu trẻ xuất hiện, nhưng hình thức con không được tối đa):

alt text

Ở giai đoạn này, biểu mẫu con không thể di chuyển được. Tuy nhiên, tôi tìm thấy một giải pháp cho điều đó, chỉ đơn giản bằng cách hiển thị và ẩn một hình thức con giả, mà buộc các hình thức con thực tế để trở thành đúng cách tối đa. Nhưng điều này làm cho khu vực MDI nhấp nháy. Đã thử các phương thức không hợp lệ, làm mới, cập nhật, nhưng chúng không giúp ích gì. Có lẽ có cách giải quyết khác để khắc phục lỗi này và không làm cho khu vực MDI nhấp nháy với hình thức con giả?

private void workaround1Button_Click(object sender, EventArgs e) 
{ 
    dummyForm.Visible = true; 
    dummyForm.Visible = false; 
} 

2) Khi biểu mẫu con được phóng to, biểu tượng của biểu mẫu con được hiển thị trên thanh trình đơn. Tuy nhiên, nếu bạn phải thay đổi biểu tượng trong khi biểu mẫu con được phóng to, biểu tượng trên thanh trình đơn không được làm mới (xem hình trên). Tôi tìm thấy một cách giải quyết cho điều đó quá, mà về cơ bản ẩn và hiển thị thanh trình đơn. Biểu tượng được làm mới, nhưng nó làm cho mọi thứ bên dưới thanh trình đơn nhấp nháy. Đã thử các phương thức không hợp lệ, làm mới, cập nhật, nhưng chúng không giúp ích gì. Có cách nào khác để làm cho thanh trình đơn làm mới biểu tượng của biểu mẫu con không?

private void workaround2Button_Click(object sender, EventArgs e) 
{ 
    menuStrip.Visible = false; 
    menuStrip.Visible = true; 
} 

Ngoài ra tôi nhận thấy rằng khi form cha đang ở chế độ trạng thái cửa sổ bình thường (không phải tối đa) và bạn thay đổi chiều rộng hoặc chiều cao của mẫu 1 pixel, hình thức con trở nên tối đa như nó phải được và biểu tượng của biểu mẫu con trên thanh trình đơn được làm mới đúng cách và bạn không cần cách giải quyết khác mà tôi đã mô tả ở trên. Nếu tôi thay đổi kích thước của formicaly formicaly, hình thức flickers bởi 1 pixel và tôi không thể làm điều đó, khi hình thức cha mẹ được tối đa. Có cách nào để tôi có thể gọi chức năng repaint/refresh được gọi khi bạn thay đổi kích thước biểu mẫu và làm cho biểu mẫu con trở nên tối đa đúng cách và biểu tượng trên thanh trình đơn được làm mới?

Trả lời

1

Tìm cách tìm hiểu những lỗi đó.

Trước hết, bạn cần phải tạm ngừng vẽ tranh cho một biểu mẫu và các con của nó. Tôi đã tìm thấy một chuỗi rất hữu ích here, mô tả cách thực hiện.

Sau khi treo sơn, bạn cần gọi phương thức UpdateBounds của điều khiển và tăng chiều rộng hoặc chiều cao của ClientRectangle một và sau đó giảm trở lại cùng giá trị trước đó. Điều này gọi chức năng bố trí mà làm cho tất cả mọi thứ để cập nhật/repaint. Bước cuối cùng là cho phép vẽ. Không phải là giải pháp rất tốt đẹp, tôi đoán, nhưng nó hoạt động.

StopDrawing(); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1); 
StartDrawing(); 

tôi thấy đình chỉ vẽ rất hữu ích không chỉ để làm việc xung quanh hai lỗi, mà còn ở chung để làm cho công việc GUI trơn tru hơn. Tôi đoán điều này có thể giúp loại bỏ bất kỳ loại nhấp nháy nào. Tuy nhiên, giải pháp này đòi hỏi P/Invokes, mà nên tránh nói chung.

1

Bạn có mệt mỏi khi sử dụng Ẩn/Hiển thị thay vì đặt hiển thị thành đúng/sai không?

Hãy thử:

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Show(); 
} 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Hide(); 
} 
+0

Có, tôi đã cố gắng, nhưng không có gì thay đổi. Tôi nghĩ childForm.Visible = true/false gọi những phương thức đó. – Povilas

+1

Thực ra nó phải là một cách khác. Ẩn/Hiển thị sau đó sẽ đặt hiển thị thành false/true. –

1

Có một lỗi trong việc thực hiện của lớp MdiControlStrip nội bộ, kiểm soát mà hiển thị các biểu tượng và các min/max/khôi phục glyphs trong cửa sổ cha mẹ. Tôi đã không mô tả nó như được nêu ra, các mã không phải là dễ dàng. Một tác dụng phụ cổ điển của lỗi là glyphs tăng gấp đôi, bạn tìm thấy một số tác dụng phụ khác. Việc sửa chữa là đơn giản, mặc dù, trì hoãn việc tạo các cửa sổ con cho đến sau khi hàm tạo được hoàn thành. Như thế này:

public MainForm() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnLoad(EventArgs e) { 
     childForm = new Form(); 
     childForm.Text = "Child Form"; 
     childForm.MdiParent = this; 

     dummyForm = new Form(); 
     dummyForm.MdiParent = this; 
     dummyForm.WindowState = FormWindowState.Maximized; 
     base.OnLoad(e); 
    } 
+0

Ah, vâng, bạn đã sử dụng sự kiện Tải. Di chuyển base.OnLoad() xuống đáy. Hoạt động trên máy của tôi ™. –

+0

Đã cố khắc phục sự cố bằng cách ghi đè phương thức OnLoad, nhưng vẫn còn hành vi lỗi tương tự. Không có gì thay đổi. Và các biểu mẫu con cần phải được tạo động, vì vậy đây sẽ không thực sự là một giải pháp cho tôi. – Povilas

1

Cách giải quyết này?

CẬP NHẬT

tôi chỉ cho bạn ý tưởng làm thế nào bạn có thể làm. Một giải pháp tốt hơn bằng cách sử dụng cùng một ý tưởng như trên sẽ là một hình thức cơ sở mới giúp tiết kiệm trạng thái cửa sổ. Xem bên dưới. Lấy các biểu mẫu của bạn từ FixedForm thay vì Biểu mẫu:

public partial class FixedForm : Form 
{ 
    private FormWindowState lastWindowState; 

    public FixedForm() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnVisibleChanged(EventArgs e) 
    { 
     base.OnVisibleChanged(e); 

     if (Visible) 
     { 
      WindowState = lastWindowState; 
     } 
     else 
     { 
      lastWindowState = WindowState; 
      WindowState = FormWindowState.Normal; 
     } 
    } 
} 
+0

Chắc chắn đây là một trong những khả năng làm thế nào để vượt qua lỗi, nhưng nó làm cho tối đa hóa hình ảnh động của các hình thức trẻ em xuất hiện hơn và hơn nữa, nó kinda gây phiền nhiễu. Cách giải quyết của tôi về điều đó nhanh hơn. – Povilas

+0

Kiểm tra cập nhật của tôi cho một giải pháp mà không cần nhấp nháy – Scoregraphic

+0

tốt, bạn có thể gửi thông báo 'WM_SIZE' đến cửa sổ cha mẹ xử lý nếu cách này giải quyết được sự cố. – Scoregraphic

0

Tại sao không chỉ tự thiết lập lại biểu tượng cần thiết trong mục menuStrip, sau khi tạo cửa sổ:

menuStripMain.Items[0].Image = null;