2012-06-17 28 views
10

Tôi có thể thiếu một cái gì đó về các nguyên tắc cơ bản của WPF thiết kế, nhưng tôi đã tự hỏi tại sao nhiều thuộc tính trên điều khiển WPF được tiếp xúc như là loại 'Object'?Tại sao nhiều thuộc tính trong WPF lại là 'Object' thay vì giao diện?

Ví dụ: MenuItem.Icon là một đối tượng và cũng là MenuItem.ToolTip. Là một người dùng gần thời gian đầu tiên, điều này rất khó hiểu với tôi (có vẻ như tôi đang sử dụng một ngôn ngữ lập trình động, không biết liệu có đặt ToolTip thành một kiểu String thậm chí sẽ hoạt động hay không). Hơn nữa, tôi đã cố gắng đặt Icon thành một 'System.Drawing.Icon' và tôi nhận được một ArgumentException của "Argument 'picture" phải là một hình ảnh có thể được sử dụng như một Icon. " Không nên gõ bất động sản để ít nhất nó có thể mô tả những gì trên thế giới mà bạn cho là nó?

Thành thật mà nói, tôi đoán vì lý do là vì bạn không thể triển khai giao diện trên một loại mà bạn không tạo (không tạo trình bao bọc), nhưng đó chỉ là phỏng đoán.

Cảm ơn rất nhiều vì câu trả lời và thông tin chi tiết của bạn!

Trả lời

2

Lý do chính trong quan điểm của tôi là vì Object là "lớp cơ sở cuối cùng của tất cả các lớp trong .Net Framework". Điều này mang lại cho bạn sự linh hoạt, trong WPF bạn không bị giới hạn trong một loại được xác định trước. Wpf là khác nhau và có một đường cong học tập, nhưng nó cung cấp cho bạn nhiều lựa chọn hơn để tạo ra một sản phẩm có vẻ tốt.

tức

Bạn có thể gán một TextBox để một ToolTip:

TextBox tb = new TextBox(); 
tb.Text = "Hello World"; 
this.ToolTip = tb; 

một Bitmap

BitmapImage myBitmapImage = new BitmapImage(new Uri((@"C:\Temp\20100706.jpg"))); 
Image image = new Image(); 
image.Source = myBitmapImage; 
this.ToolTip = image; 

và gán một hình ảnh cho một MenuItem

BitmapImage myBitmapImage = new BitmapImage(new Uri((@"C:\Temp\20100706.jpg"))); 
Image image = new Image(); 
image.Source = myBitmapImage; 
menuItem1.Icon = image; 
+0

Tôi nghĩ điều đó thật tuyệt, nhưng đối tượng không phải là một yếu tố giao diện người dùng nào đó? Cả TextBox và Image đều là FrameworkElements. Điều duy nhất tôi đã thấy rằng bạn có thể chỉ định đó không phải là một FrameworkElement là một String ... đó thực sự là điều duy nhất? Nếu như vậy nó có vẻ như không phải là một lý do tốt cho nó để được 'Object' như tôi chỉ có thể tạo ra một Label hoặc wrapper quanh String của tôi. – Trevor

+0

@Rovert Không, nó phụ thuộc vào tài sản, nếu có một khía cạnh trực quan với nó và một cách để WPF chuyển đổi nó thành một hình ảnh thì nó sẽ được hiển thị. Bạn có thể gán * bất cứ thứ gì * cho một đối tượng. Tôi tin rằng nó là một sản phẩm của [TypeConversion] (http://msdn.microsoft.com/en-us/library/aa970913.aspx) cần thiết để thực hiện công việc đánh dấu Xaml. –

+0

Điểm thú vị về TypeConversion. Điều đó thực sự có ý nghĩa hơn rất nhiều về cách thức và những gì nó quyết định nó có thể hiển thị. Ví dụ, tìm đến ImageSource để tìm ra cách họ làm việc dẫn đến một sự nhầm lẫn lớn, nhưng bây giờ tôi biết phải có một số hành vi năng động xảy ra đằng sau hậu trường. Cảm ơn! – Trevor

1

Hãy xem xét ToolTip chẳng hạn. Chú giải công cụ là ContentControl, trong đó có thể chứa bất kỳ loại đối tượng CLR (Common Language Runtime) nào (chẳng hạn như chuỗi hoặc đối tượng DateTime) hoặc đối tượng UIElement (chẳng hạn như Hình chữ nhật hoặc Bảng điều khiển). Điều này cho phép bạn thêm nội dung đa phương tiện vào các nút điều khiển như Nút và Hộp kiểm.

Vì lý do này, các thành phần như ToolTip được hiển thị dưới dạng Object, đó là gốc của cấu trúc phân cấp loại (với kết quả dễ sử dụng, linh hoạt và rõ ràng của mã).

0

Hãy tưởng tượng các thuộc tính này được nhập là UIElements (hoặc một số đối tượng cụ thể khác của WPF). Bạn sẽ thêm đối tượng vào các điều khiển của mình không phải là UIElements như thế nào?

Bạn sẽ phải cung cấp trình bao bọc bắt nguồn từ đối tượng WPF hiển thị thông tin bạn yêu cầu. Hầu hết thời gian, trình bao bọc sẽ chỉ gọi ToString() của đối tượng đang được bao bọc. Nhìn thấy như hầu hết các loại, bạn sẽ sử dụng cung cấp một thực hiện mặc định đủ tốt ToString() nó có ý nghĩa để chỉ cần gọi này thay vì làm cho các nhà phát triển viết wrappers cho tất cả mọi thứ.

Thứ hai, hãy tưởng tượng xem chúng có được nhập là một số giao diện hay không. Điều gì sẽ xảy ra nếu bạn muốn giao tiếp một cái gì đó mà giao diện này không thể?Các tùy chọn duy nhất là (a) các nhà phát triển sống với những hạn chế của khuôn khổ hoặc (b) Microsoft cập nhật giao diện và phá vỡ tất cả các mã hiện có đã được viết.

Cũng xem xét nếu bạn đang sử dụng mẫu như MVVM. Thiết kế hiện tại có nghĩa là các mô hình khung nhìn của bạn có thể phơi bày các thuộc tính không gắn với WPF theo bất kỳ cách nào mà cuối cùng làm cho mã của bạn có thể tái sử dụng được trên các công nghệ khác nhau.

Cuối cùng, hãy nhớ rằng có sự khác biệt giữa đối tượng đại diện cho thuộc tính và cách mà WPF hiển thị thông tin đó. VÍ DỤ. nếu bạn sử dụng kiểu nguyên thủy như System.String, WPF sẽ tạo khối chữ và đặt thuộc tính văn bản thành kết quả là ToString(). Điều này cho phép tách biệt rất rõ ràng giữa các dữ liệu được hiển thị bởi giao diện người dùng và cách chúng thông tin là trả về bởi giao diện người dùng.

Đi một lớp đơn giản mà đại diện cho một mục trình đơn, ví dụ:

public class MenuItem 
{ 
    public string Text { get; set; } 
    public bool IsChecked { get; set; } 
    public bool IsEnabled { get; set; } 
} 

loại này chỉ cho thấy dữ liệu về các mục trình đơn và không có thông tin về cách thông tin này nên được trả lại. Trong thực tế, ngoài tên của lớp (MenuItem) điều này thậm chí không cụ thể cho một mục trình đơn và dữ liệu giống nhau có thể được sử dụng trong một điều khiển giao diện người dùng khác như hộp danh sách đã chọn mà không cần thay đổi. Nếu lớp tiếp xúc với các phần tử giao diện người dùng cụ thể của WPF thì thông tin sẽ cần phải được điều chỉnh theo loại khác cho mỗi điều khiển giao diện người dùng khác nhau.

Các vấn đề liên quan