Почему в WPF много свойств "Объект" вместо интерфейса?

Возможно, мне что-то не хватает в основах дизайна WPF, но мне было интересно, почему многие свойства элементов управления WPF отображаются как тип "Объект"?

Например, MenuItem.Icon является объектом, а также MenuItem.ToolTip. Как почти первый пользователь, это меня очень сбивало с толку (мне казалось, что я использую динамический язык программирования, не имея понятия, будет ли работать ToolTip с типом String или нет). Более того, я попытался установить Icon в "System.Drawing.Icon", и я получаю ArgumentException из "Аргумент", изображение должно быть изображением, которое можно использовать в качестве значка ". Не следует ли вводить свойство, чтобы он мог, по крайней мере, описать, что в мире вы должны дать?

Честно говоря, я предполагаю, что причина заключается в том, что вы не можете реализовать интерфейс по типу, который вы не создали (без создания обертки), но это просто предположение.

Большое спасибо за ваши ответы и идеи!

Ответ 1

Основная причина, по моему мнению, заключается в том, что поскольку Object является "базовым классом всех классов в .NET Framework", Это дает вам гибкость, в WPF вы не ограничены предопределенным типом. Wpf отличается и имеет кривую обучения, но он дает вам гораздо больше возможностей для создания продукта, который выглядит хорошо.

то есть.

Вы можете назначить TextBox для подсказки:

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

Растровое изображение

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

и присвоение изображения элементу MenuItem

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

Ответ 2

Рассмотрим пример ToolTip. ToolTip - это ContentControl, который может содержать любой тип объекта CLR (Common Language Runtime) (например, строка или объект DateTime) или объект UIElement (например, прямоугольник или панель). Это позволяет вам добавлять богатый контент для таких элементов управления, как Button и CheckBox.

По этой причине такие элементы, как ToolTip, отображаются как Object, то есть корень иерархии типов (с учетом простоты использования, гибкости и ясности кода).

Ответ 3

Представьте, что эти свойства были напечатаны как UIElements (или какой-либо другой специфичный для WPF объект). Как бы вы добавляли объекты к своим элементам управления, которые не были UIElements?

Вам нужно будет предоставить оболочку, полученную из объекта WPF, который предоставляет требуемую информацию. Большую часть времени оболочка просто вызывала ToString() объекта, который был обернут. Увидев, что большинство типов, которые вы будете использовать, обеспечивают достаточно хорошую реализацию по умолчанию для ToString(), имеет смысл просто вызвать это вместо того, чтобы разработчик писал обертки для всего.

Во-вторых, представьте, были ли они введены как некоторый интерфейс. Что делать, если вы хотите сообщить что-то, чего не может этот интерфейс? Единственные параметры: (a) разработчик живет с ограничениями фреймворка или (б) Microsoft обновляет интерфейс и разбивает весь существующий код, который уже был написан.

Также рассмотрим, используете ли вы шаблон, подобный MVVM. Текущий дизайн означает, что ваши модели просмотра могут выставлять свойства, которые никак не связаны с WPF, что в конечном итоге делает ваш код более многократно использованным для разных технологий.

Наконец, помните, что существует разница между объектом, который представляет свойство, и тем способом, которым WPF отображает эту информацию. НАПРИМЕР. если вы используете примитивный тип, такой как System.String, WPF создаст текстовый блок и задает свойство text для результата ToString(). Это позволяет очень чистое разделение между данными, отображаемыми пользовательским интерфейсом, и они способствуют тому, что информация визуализируется с помощью пользовательского интерфейса.

Возьмем простой класс, который представляет пункт меню, например:

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

Этот тип предоставляет только данные о элементе меню и не содержит информации о том, как эта информация должна отображаться. На самом деле, помимо имени класса (MenuItem), это даже не характерно для элемента меню, и одни и те же данные могут использоваться в другом элементе управления пользовательским интерфейсом, например, в отмеченном списке, без каких-либо изменений. Если класс подвергается конкретным элементам пользовательского интерфейса WPF, тогда информация должна быть адаптирована другим типом для каждого интерфейса управления пользовательским интерфейсом.