WPF: Как мне настроить мою модель и стратегию привязки? - PullRequest
0 голосов
/ 19 июня 2010

Рассмотри это изображение: альтернативный текст http://img25.imageshack.us/img25/9743/timetablepo.png

TimeTableViewModel этого пользовательского интерфейса выглядит так:

public string SchoolclassCodeMonday {get;set;}
public string SchoolclassCodeTuesday {get;set;}
public string SchoolclassCodeWednesday {get;set;}
public string SchoolclassCodeThursday {get;set;}
public string SchoolclassCodeFriday {get;set;}
public string SchoolclassCodeSaturday {get;set;}
public string SchoolclassCodeSunday {get;set;}

Выше будет работать, когда я отобразил бы только свойства в виде строки в текстовом поле. Но я хочу связать каждый комбокс с взаимной ObservableCollection SchoolclassCodes и SelectedItem, также известный как DisplayMember ComboBox, должен как-то быть НАСТРОЕНО в одно из 7 вышеупомянутых свойств И SelectedItem, если он получен, должен содержать строку из всех 7 школьных классов, выбранных в выпадающем списке.

Или то, что я на самом деле хочу просто другими словами; -)

Показать в ComboBox список SchoolclassCodes, установить значение SelectedItem.SchoolclassCode "WeekdayName" на значение выбранного ComboboxItem.SchoolclassCode

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

Я мог бы добавить к TimeTableViewModel для каждого свойства a ObservableCollection SchoolclassCodes но это мне кажется очень излишним. Зачем мне хранить 7 списков для ОДНОЙ строки, если в каждой ячейке один и тот же список с одинаковыми элементами?

Любые предложения относительно структуры ViewModels и привязки в Wpf приветствуются:)

ОБНОВЛЕНИЕ : Мой SchoolclassCodes список создается динамически, поэтому у меня нет возможности статического связывания или элементов строки с жестким кодом в XAML ...

UPDATE2:

ОК. Я пытался заставить его работать с MVVM:

Мне пришлось изменить ObservableCollection ClassCodes до ObservableCollection SchoolclassCodes как объект Schoolclass содержит ссылку на класс Pupil со строками, которые невозможны.

Schoolclass.cs:

public string SchoolclassCode {get;set;}
...

TimeTableWeekViewModel.cs:

public ObservableCollection<Schoolclass> SchoolclassCodes
    {
        get { return _schoolclassCodes; }
        set
        {
            _schoolclassCodes = value;
            this.RaisePropertyChanged("SchoolclassCodes");
        }
    }

XAML:

Как должна выглядеть привязка СЕЙЧАС, потому что wcf не находит SchoolclassCodes?

Ответы [ 3 ]

1 голос
/ 20 июня 2010

Я рекомендую вам взглянуть на шаблон MVVM (Model-View-ViewModel), если вы делаете что-то дистанционно сложное. Кроме того, полезно реализовать INotifyPropertyChanged в вашей модели / модели представления (например, класс MyWeek в моем примере ниже). Это будет уведомлять о любых других привязках всякий раз, когда изменяется одно из ваших SchoolclassCode<Day> свойств.

Вот простой пример кода, с которого можно начать:

using System.Collections.ObjectModel;
using System.Linq;

namespace BindingSample
{
    public partial class Window1
    {
        public Window1()
        {
            InitializeComponent();
            SchoolclassCodes = new ObservableCollection<string>(
                Enumerable.Range(1, 10).Select(i => "Code #" + i));
            MyWeeks = new ObservableCollection<MyWeek>(
                Enumerable.Range(1, 5).Select(i => new MyWeek() {SchoolclassCodeMonday = SchoolclassCodes.First()}));
            DataContext = this;
        }

        public ObservableCollection<string> SchoolclassCodes { get; private set; }
        public ObservableCollection<MyWeek> MyWeeks { get; private set; }
    }

    public class MyWeek
    {
        public string SchoolclassCodeMonday { get; set; }
        public string SchoolclassCodeTuesday { get; set; }
        public string SchoolclassCodeWednesday { get; set; }
        public string SchoolclassCodeThursday { get; set; }
        public string SchoolclassCodeFriday { get; set; }
        public string SchoolclassCodeSaturday { get; set; }
        public string SchoolclassCodeSunday { get; set; }
    }
}

<Window x:Class="BindingSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <CollectionViewSource x:Key="ClassCodes" Source="{Binding SchoolclassCodes}" />
    </Window.Resources>
    <ListView ItemsSource="{Binding MyWeeks}">
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Header="Monday">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox SelectedValue="{Binding SchoolclassCodeMonday}"
                                          ItemsSource="{Binding Source={StaticResource ClassCodes}}"
                                          IsSynchronizedWithCurrentItem="False" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <!-- Other columns here... -->
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>
</Window>
0 голосов
/ 20 июня 2010

Вам не нужно возиться с DataGrid, и вам, конечно, не нужно создавать какой-либо класс с семью различными свойствами, для которого вам нужно реализовать уведомление об изменении свойства. Элемент управления Grid делает календари простыми.

Ваша модель представления должна иметь три класса: Month, Week и Day. Класс Week содержит список Day объектов, а класс Month имеет список Week объектов. Каждый класс должен иметь ссылку на своего родителя, то есть Week в Day и Month в Week.

Конструктор класса Week должен инициализировать свое свойство Days как список из 7 Day объектов. Конструктор класса Month должен иметь более конкретную логику для настройки его свойства Weeks; Я оставлю это тебе.

Объект Day должен предоставлять следующие свойства:

public DayOfWeek DayNumber { get; private set; }
public ObservableCollection<SchoolclassCode> Codes { get { return Week.Codes; } }

, а также свойство для чтения / записи Code, которое отправляет уведомление об изменении свойства.

Объект Week должен выставить:

public ObservableCollection<SchoolclassCode> Codes { get { return Month.Codes; } }
public IEnumerable<Day> Days { get; private set; }
public IEnumerable<string> Codes
{
   get { return Days.Select(x => x.Code); }
}

Затем вы можете определить шаблон данных для представления дней:

<DataTemplate DataType="{x:Type local:Day}">
   <Grid>
      <Grid.ColumnDefinitions>
         <ColumnDefinition SharedSizeGroup="Sunday"/>
         <ColumnDefinition SharedSizeGroup="Monday"/>
         <ColumnDefinition SharedSizeGroup="Tuesday"/>
         <ColumnDefinition SharedSizeGroup="Wednesday"/>
         <ColumnDefinition SharedSizeGroup="Thursday"/>
         <ColumnDefinition SharedSizeGroup="Friday"/>
         <ColumnDefinition SharedSizeGroup="Saturday"/>
      </Grid.ColumnDefinitions>
      <ComboBox 
         Grid.Column="{Binding DayNumber}" 
         ItemsSource="{Binding Codes}" 
         SelectedValue="{Binding Code, Mode=TwoWay}"/>
   </Grid>
</DataTemplate>

и недели:

<DataTemplate DataType="{x:Type Week}">
  <ItemsControl ItemsSource="{Binding Days}">
    <ItemsControl.ItemTemplate>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</DataTemplate>

и месяцы:

<DataTemplate DataType="{x:Type Month}">
  <ItemsControl ItemsSource="{Binding Weeks}" Grid.IsSharedSizeScope="True">
    <ItemsControl.ItemTemplate>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Vertical"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</DataTemplate>

Добавление названий дней и номеров недель к указанным выше шаблонам просто.

0 голосов
/ 20 июня 2010

Поскольку столбцы должны генерироваться автоматически, размещение этого кода в соответствующем месте (Loaded событие?) Должно делать то, что вы хотите:

        ObservableCollection<String> Collection = GetCollection();

        foreach (DataGridComboBoxColumn column in DataGrid1.Columns.OfType<DataGridComboBoxColumn>())
        {
            column.ItemsSource = Collection;
        }

Конечно, некоторые модификации должны быть применены!

...