Перетаскивание из источника данных в окно WPF не работает
Мне было поручено разработать программу управления контактами для моей компании. У нас есть VS 2012, и так как я никогда не использовал WPF, я думал, что буду использовать его для разработки этого приложения.
У меня огромная проблема с началом связывания при использовании структуры сущностей для базы данных, которая, между прочим, является базой данных первой.
Я следовал инструкциям в этой ссылке на письмо. http://msdn.microsoft.com/en-us/data/jj574514.aspx
Объекты отображаются в окне источников данных просто отлично. Но когда я перетаскиваю в окно, ничего не происходит. Понятия не имею, что я делаю неправильно, и не могу найти кого-то еще с этой проблемой.
Может кто-нибудь помочь мне здесь? Я посмотрел везде. Любая помощь приветствуется
4 ответа
Хорошо. Я на самом деле прочитал эту статью, просто чтобы показать добросовестность и дать вам понять, что я действительно хочу вам помочь.
Я пришел к следующим выводам:
- В этой статье показан очень простой сценарий получения данных из контекста Entity Framework и отображения их в WPF DataGrid.
- У него нет ни каких-либо проверок, ни бизнес-правил.
- Он не имеет поведения пользовательского интерфейса, такого как условное включение / отключение или отображение / скрытие каких-либо элементов пользовательского интерфейса.
- В таком сценарии конструктор полезен, когда на самом деле вам ничего не нужно, кроме как получать / сохранять данные из / в БД.
- К сожалению (или к счастью для всех нас, разработчиков, которые зарабатывают на этом), большинству приложений требуется некоторый уровень проверки и бизнес-правила, а также некоторый уровень логики пользовательского интерфейса.
- Дизайнер действительно бесполезен, когда дело доходит до разработки сложной логики.
Вы можете использовать конструктор для таких ситуаций, когда вам не требуется сложная логика, однако я должен предупредить вас о следующих минусах:
- Дизайнер Visual Studio WPF создает пользовательские интерфейсы фиксированного размера и фиксированного положения. пользовательские интерфейсы такого типа не работают при работе на компьютерах с разными разрешениями экрана и настройками DPI. Так же, как winforms.
- Он также производит XAML, который имеет много ненужных вещей (таких как
x:Name="categoryIdColumn"
и тому подобноеMargin="13,13,43,191"
которые действительно плохи с точки зрения поддержания / масштабируемости) - Из того, что я видел, созданный дизайнером XAML также содержит
CollectionViewSource
Это и хорошо, и плохо. Это хорошо, потому что это позволяетDesign-Time Data
в DataGrid, но это также плохо, потому что он раздувает ваш XAML с большим количеством ненужных вещей и вводит ненужные<Window.Resources>
это усложняет ситуацию.
Теперь это очень минимальный XAML, необходимый для этой DataGrid без поддержки данных времени разработки:
<Window x:Class="MiscSamples.DesignTimeDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DesignTimeDataGrid">
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGridTextColumn Header="Category Id" Binding="{Binding CategoryId}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
</DataGrid>
</Window>
Ты видишь? На самом деле это быстрее набрать это (гораздо больше с помощью Intellisense), чем то, что вам нужно, чтобы просмотреть окно свойств и установить эти свойства вручную.
Я предлагаю вам познакомиться с XAML, а не настаивать на сложном пути
Еще один очень важный аспект, который следует иметь в виду, заключается в том, что, вообще говоря, вы ничего не вкладываете в программный код в WPF, потому что он не нужен, поэтому этот учебник фактически идет вразрез с WPF, а это нормально, потому что на самом деле учебник Entity Framework, а не учебник WPF.
простота разработки
Вам действительно нужно пересмотреть то, что вы называете "простота разработки". Когда дело доходит до разработки пользовательского интерфейса, я называю "простотой разработки" фактическую возможность делать то, что я хочу с пользовательским интерфейсом, без необходимости прибегать к дурацким процедурам процедурного кода с использованием P/Invoke (что бы это ни значило) и типа "рисование владельца" вещей для вечности.
WPF обеспечивает НАСТОЯЩУЮ простоту разработки, в отличие от ложной простоты разработки, которую демонстрируют winforms
winforms позволяет вам делать все с дизайнером (и это только потому, что код, который сгенерировал дизайнер, на самом деле настолько дерьмовый, что никто бы никогда не использовал winforms, если бы у них не было дизайнера), но когда дело доходит до добавления сложных DataBinding или UI логика вы застряли с неспособностями winforms навсегда.
WPF поощряет ручное написание XAML не только потому, что XAML является декларативным (в отличие от процедурного подхода winforms), но и потому, что уровни настраиваемости и повторного использования настолько высоки, что подход, ориентированный на дизайнера, не имеет смысла.
перетаскивание является простым выходом
Нет, это не так. Это на самом деле трудный путь. Самый простой способ - выучить XAML и научиться делать то, что вы даже не можете себе представить, с winforms.
Если подход, ориентированный на дизайнера, все еще имеет смысл для вас, вы можете попробовать Expression Blend
Автоматически создавать сетки данных из ваших моделей
Использование источника данных для перетаскивания шаблона на элемент управления WPF - это отличный и быстрый способ начать работу!
Начните с этого: в вашем проекте создайте папку с именем Models, затем сначала используйте либо Entity Framework DB, либо от руки код модели, которую вы хотите показать.
В этой же папке создайте фиктивный класс, который является свойством для IEnumerable следующим образом.
public IEnumerable<MyClassModel> MyCollection { get; set; }
Оттуда перейдите в главное меню Visual Studio, выберите View/Other Windows/Data Source и щелкните по этой ссылке.
Нажмите на Object и найдите только что созданное свойство MyCollection.
Теперь откройте пользовательский элемент управления или окно в WPF, но оставьте панель инструментов источников данных открытой.
По умолчанию это должен быть DataGrid, но вы можете щелкнуть правой кнопкой мыши на источнике данных и изменить его на детализацию, сетку данных или выбрать отдельные свойства класса, который он представляет.
Просто перетащите этот источник данных в область сетки XAML. Щелкните правой кнопкой мыши новый материал, который вы видите, и нажмите "Сброс", чтобы установить размер содержимого всего окна.
После того, как вы это сделаете, вы вставите код в код позади представления, как показано ниже в событии загрузки этого окна, пользовательском контроле и т. Д.
// Do not load your data at design time.
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
//Load your data here and assign the result to the CollectionViewSource.
System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource)this.Resources["Resource Key for CollectionViewSource"];
myCollectionViewSource.Source = your data
// }
Вернитесь к XAML и найдите свойство CollectionViewSource KEY, которое также было вставлено при перетаскивании свойства в XAML. Это выглядит так:
Используйте имя ключа в коде позади, а затем "привяжите" CVS к вашему источнику данных, который является перечислимым типом MyClassModel, он может жить в модели представления или в коде позади представления, как вы выберете.
Если вы используете только CollectionViewSource в качестве datacontext сетки, вам не нужно реализовывать INPC для каких-либо базовых коллекций! CVS обновляет представление автоматически при каждом обновлении источника! Как только вы это сделаете, вы сможете создать рабочие View прототипы данных за 2 минуты! Забудьте код XAML, который просто занимает слишком много времени.
Для тех, кто обнаружит эту проблему в VS 2022: как написано, в VS 2022 есть эта известная ошибка, которая не позволяет перетаскивать источник данных в форму XAML.
Дополнительная информация: https://developercommunity.visualstudio.com/t/drag-aa-table-from-datasource-and-drop-in-a-windo/1660788 .
ОБНОВЛЕНИЕ: говорится, что исправление было выпущено 15 июня. Вы можете попробовать обновить VS 2022 до последней версии.
Поскольку фиктивный класс имеет свойство только дляIEnumerable
нравиться:
public IEnumerable<MyClassModel> MyCollection { get; set; }
Тогда разве не является большим шагом вперед возможность определить более сложную коллекцию аккомпанементов, которая происходит глубже изIEnumerable<MyClassModel>?
Хотя следующие ссылки посвящены дизайнеру Windows FORMS, по словам Брайана Нойеса в его курсе Pluralsight WPF Productivity,
https://www.pluralsight.com/courses/wpf-productivity-playbook
Дизайнер WPF основан на дизайнере Windows Forms. Информация в этих ссылках и ссылках внутри них показывает способ настройки источников данных, а также элементы управления макетом контейнеров/UI и значки, которые их представляют (которые отображаются сбоку от источников данных):
https://devblogs.microsoft.com/dotnet/state-of-the-windows-forms-designer-for-net-applications/
https://devblogs.microsoft.com/dotnet/databinding-with-the-oop-windows-forms-designer/