сетка данных инструментария wpf

привет, я создаю приложение wpf с сетками данных, шаблон - это модель представления модели.

все мои экраны содержат элемент управления контентом, и я просто назначаю ему модель представления с подходящим шаблоном данных,

в любом случае, моя проблема связана с столбцом поля со списком, контекст данных - это представленная сущность, и мне нужно, чтобы она была моделью представления.

какое лучшее решение?


person Chen Kinnrot    schedule 08.06.2009    source источник


Ответы (4)


Я использую другую сетку данных, но она может быть похожей. Я сделал это так:

в XAML я определил ObjectDataProvider в ресурсах:

<ObjectDataProvider x:Key="VM" ObjectInstance="{x:Null}" x:Name="vm"/>

затем, назначив DataContext (конструктор или событие DataContextChanged), я сделал следующее:

(this.Resources["VM"] as ObjectDataProvider).ObjectInstance = this.DataContext;

В Combobox xaml я использовал это как источник привязки:

ItemsSource="{Binding Source={StaticResource VM}, Path=SomeItems, Mode=OneWay}"

Не уверен, работает ли это с сеткой данных Microsoft, но я думаю, что стоит попробовать.

person Botz3000    schedule 12.06.2009
comment
да. Насколько мне известно, оба элемента не являются непосредственно частью визуального дерева, поэтому что-то вроде этого может это сделать. - person Botz3000; 12.06.2009

вот как я использовал ViewModel с ComboBoxes, DataContext - это ViewModel, а не базовая сущность (List ‹Person›).

ViewModel (Person - это простой класс с именем и возрастом):

public class PeopleViewModel : INotifyPropertyChanged
{
    private List<Person> _peopleList;
    private Person _selectedPerson;

    public PeopleViewModel()
    {
        // initialize with sample data
        _peopleList = getPeopleList();
    }

    // gets sample data
    private List<Person> getPeopleList()
    {
        var result = new List<Person>();
        for (int i = 0; i < 10; i++)
        {
            result.Add(new Person("person " + i, i));
        }
        return result;
    }

    public List<Person> PeopleList
    {
        get { return _peopleList; }
    }

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            if (_selectedPerson == value) return;
            _selectedPerson = value;
            // required so that View know about changes
            OnPropertyChanged("SelectedPerson");
        }
    }
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    // WPF will listen on this event for changes
    public event PropertyChangedEventHandler PropertyChanged;
}

XAML для ComboBox:

<ComboBox Name="cmbEnum" Width="150" ItemsSource="{Binding Path=PeopleList}" SelectedValue="{Binding Path=SelectedPerson}" SelectedValuePath="" DisplayMemberPath="Name" ></ComboBox>

А в коде позади я могу:

    public Window2()
    {
        InitializeComponent();

        vm = new PeopleViewModel();
        // we are listening on changes of ViewModel, not ComboBox
        vm.PropertyChanged += new PropertyChangedEventHandler(vm_PropertyChanged);
        this.DataContext = vm;
    }

    void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    if (e.PropertyName == "SelectedPerson")
    {
        MessageBox.Show(vm.SelectedPerson.Age.ToString());
    }
    }

    // button1_Click should be probably replaced by Command
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        // sample showing that GUI is updated when ViewModel changes
    vm.SelectedPerson = vm.PeopleList[2];
    }

Надеюсь, это поможет, я новичок в WPF, я хотел бы услышать какие-либо отзывы, если это правильный способ использования MVVM, я думаю, что это довольно элегантно, поскольку вы имеете дело только с ViewModel и Model в коде, а View можно заменить.

person Martin Konicek    schedule 13.06.2009

Я обнаружил, что лучший способ реализовать это - определить какой-то внешний класс для всех поисков, которые я использую в сетке, и встроить их в шаблон как статический ресурс.

person Chen Kinnrot    schedule 15.06.2009

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

(вы не можете сделать сам класс статическим, иначе XAML не сможет его открыть, но вы не получите ошибок компиляции)

Например:

public class ZoneList
{
  private static readonly IList<Zone> _Items = new List<Zone>();
  public static IList<Zone> Items
  {
    get { return _Items; }
  }
}

а затем в XAML:

<UserControl.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="myZoneList"   ObjectType="{x:Type StaticLists:ZoneList}"/>
    </ResourceDictionary>
</UserControl.Resources>

<ComboBox ItemsSource="{Binding Path=Items, Source={StaticResource myZoneList}}"></ComboBox>
person John Weldon    schedule 18.06.2009