Как установить datacontext пользовательского элемента управления - PullRequest
6 голосов
/ 17 мая 2010

Я пишу приложение в WPF, используя инструментарий MVVm, и у меня проблемы с подключением viewmodel и view.

Модель создана с использованием структуры сущности ado.net.

Модель представления:

public class CustomerViewModel
    {
        private Models.Customer customer;
        //constructor
        private ObservableCollection<Models.Customer> _customer = new ObservableCollection<Models.Customer>();
        public ObservableCollection<Models.Customer> AllCustomers
        {
            get { return _customer; }

        }
        private Models.Customer _selectedItem;
        public Models.Customer SelectedItem
        {
            get { return _selectedItem; }

        }
        public void LoadCustomers()
        {
            List<Models.Customer> list = DataAccessLayer.getcustomers();
            foreach (Models.Customer customer in list)
            {
                this._customer.Add(customer);
            }
            }
        }

И вид (без кода на данный момент):

<UserControl x:Class="Customers.Customer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:vm ="clr-namespace:Customers.ViewModels"
             d:DesignHeight="300" d:DesignWidth="300"
             xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" >

    <Grid>
        <toolkit:DataGrid ItemsSource="{Binding AllCustomers}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" AutoGenerateColumns="True">

        </toolkit:DataGrid>

        <toolkit:DataGrid ItemsSource="{Binding SelectedItem.Orders}">

        </toolkit:DataGrid>



    </Grid>
</UserControl>

И класс доступа к данным:

 class DataAccessLayer
    {
        public List<Customer> customers = new List<Customer>();

        public static List<Customer> getcustomers()
        {
            entities db = new entities();

            var customers = from c in db.Customer.Include("Orders")
                           select c;
            return customers.ToList();
        }


    }

Проблема в том, что данные не отображаются просто потому, что контекст данных не установлен. Я пытался сделать это в коде позади, но это не сработало. Я бы все равно предпочел сделать это в файле xaml. Другая проблема связана с привязкой SelectedItem - код никогда не используется.

Ответы [ 3 ]

6 голосов
/ 18 мая 2010

Поскольку здесь используется парадигма MVVM, я бы скопировал вашу ViewModel в конструктор для View. Мои View / ViewModels обычно следуют этой последовательности событий:

  1. Просмотр экземпляра
  2. Просмотр экземпляров конструктора ViewModel
  3. ViewModel инициализирует
  4. ViewModel запускает процедуры получения данных (отдельный поток)
  5. ViewModel вызывает OnPropertyChanged (""), чтобы предупредить View, что что-то изменилось; проверить все

Моя ViewModel создается из кода XAML (извините, это в VB.NET, я не достаточно хорошо изучил C #, чтобы доверять ему):

Public Sub New()
    MyBase.New()
    Me.DataContext = New EditShipmentViewModel(Me) 'pass the view in to set as a View variable
    Me.InitializeComponent()
End Sub

Изначально я надеялся получить что-то вроде

<UserControl>
    <UserControl.DataContext>
        <Local:EditShipmentViewModel>
    </UserControl.DataContext>
</UserControl>

Но это не сработало так, как я хотел.

Надеюсь, это немного поможет.

1 голос
/ 19 января 2013

Я установил свой текстовый объект viewmodel так же, как наблюдал за Blend4. То есть, если моя view-модель называется MainViewModel, я ссылаюсь на нее в виде:

 <UserControl.Resources>
    <local:MainViewModel x:Key="MainViewModelDataSource" />
 </UserControl.Resources>

 <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource MainViewModelDataSource}}">
    ...view xaml stuff

 </Grid>

также, если вы загружаете данные из базы данных в конструктор вашей модели представления, не забудьте добавить вспомогательный метод вокруг него, например:

  if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
        {
             myCollection = new ObservableCollection<Blah>(something);
        }

, чтобы Visual Studio / Blend4 не вылетал при попытке получить данные из соединения с базой данных в Designer. Лично я загружаю данные в конструктор довольно часто, просто потому, что мне это нужно сразу, и чтобы они кэшировались в памяти при запуске.

:)

1 голос
/ 17 мая 2010

Это это , что вы ищете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...