Коллекция привязок Silverlight к Combobox в DataForm с использованием MVVM

У меня такая проблема, у меня есть приложение Silverlight, написанное с использованием MVVM. Мне нужно создать DataForm, который привязан к свойству в ViewModel, и я хочу добавить ComboBox и заполнить его значениями из другой коллекции в той же ViewModel.

Код:

<dataFormToolkit:DataForm CurrentItem="{Binding NewUser, Mode=TwoWay}" AutoGenerateFields="False" Height="298">
            <dataFormToolkit:DataForm.EditTemplate>
                <DataTemplate>
                    <StackPanel>

                        <dataFormToolkit:DataField Label="Email">
                            <TextBox Text="{Binding Email, Mode=TwoWay}"/>
                        </dataFormToolkit:DataField>

                        <dataFormToolkit:DataField Label="Język">
                            <ComboBox ItemsSource="{Binding Path=Languages, Mode=TwoWay}"/>
                        </dataFormToolkit:DataField>

                    </StackPanel>
                </DataTemplate>
            </dataFormToolkit:DataForm.EditTemplate>
        </dataFormToolkit:DataForm>

Все это обрабатывается NewAccountVM, который имеет следующие свойства:

private User newUser;
    public User NewUser { 
        get 
        { 
            return newUser; 
        }
        set
        {
            if (value != newUser)
            {
                newUser = value;
                RaisePropertyChanged("NewUser");
            }
        }
    }

    private ObservableCollection<Language> languages;

    public ObservableCollection<Language> Languages
    {
        get { return languages; }
        set 
        {
            if (languages != value)
            {
                languages = value;
                RaisePropertyChanged("Languages");
            }
        }
    }

Теперь все это работает, помимо добавления ItemsSource в ComboBox. Я нашел много примеров, показывающих, как заполнить CB в CodeBehind, но, как я уже сказал, я хочу сделать это в стиле MVVM :) Я понимаю, что ComboBox унаследовал DataContext от DataForm, и этот ItemsSource = "{Binding Path = Languages, Mode = TwoWay} "не сработает, но я понятия не имею, как достичь своей цели.

Кто-нибудь может мне помочь?


person michajas    schedule 30.11.2009    source источник


Ответы (3)


1) Объявите модель представления для представления в разделе ресурсов.

<UserControl.Resources>
    <local:MyViewModel x:Key="myViewModel" />
</UserControl.Resources>

2) Привяжите ComboBox к свойству коллекции в модели просмотра.

<ComboBox ItemsSource="{Binding Path=Languages, 
                                Source={StaticResource myViewModel}, 
                                Mode=TwoWay}"/>
person DaveB    schedule 01.12.2009
comment
Спасибо, вот и все :) Я понял это, eriler, но у меня была проблема с моей ViewModel, потому что у нее было 2 конструктора, мне пришлось реорганизовать создание моих ViewModels на эту со статическими ресурсами. Еще раз спасибо. - person michajas; 02.12.2009
comment
В этом примере где вы устанавливаете ViewModel как DataContext для UserControl? Я предполагаю, что вы делаете это в конструкторе UserControl, но мне хотелось бы знать наверняка. - person Andrew Garrison; 21.05.2010
comment
@michajas Будьте осторожны с настройкой виртуальной машины внутри ресурсов, если ваша виртуальная машина генерирует исключение, она будет поглощена ошибкой синтаксического анализа XAML. Я настоятельно рекомендую установить виртуальную машину в событии Loaded и использовать контейнер IoC для большей гибкости. - person Agies; 26.05.2010
comment
Объединение этих двух сработало для меня weblogs.asp.net/dwahlin/archive/2009/08/20/ И msmvps.com/blogs/deborahk/archive/2009/11 / 25 / - person captonssj; 22.04.2013

вы можете установить контекст данных в XAML для своего статического ресурса следующим образом:

<UserControl.DataContext>
    <Binding Source="{StaticResource myViewModel}" />
</UserControl.DataContext>
person Chooksii    schedule 25.05.2010

Сценарий A: 1. Предположим, вы хотите заполнить комбинацию всеми ролями членства и позволить клиенту выбрать роль и назначить ее пользователю: т.е. ObjectA: Aspnet_Role, то есть ObjectB: User

  1. Допустим, User.MembershipRoleId должен быть привязан к Aspnet_Role.RoleId.

  2. Форма данных привязана к ObjectB

  3. Поле со списком в форме данных заполняется списком
  4. В XAML напишите следующее:

    <Combobox DisplayMemberPath="RoleName" SelectedValue="{Binding MembershipRoleId,Mode=TwoWay}" SelectedValuePath="RoleId" />

здесь отображение: ObjectB.MembershipRoleId = ObjectA.RoleId

Сценарий B: 1. Если вы не хотите явно определять путь в ScenarioA, тогда в этом случае определите отношение ForeignKey-PrimaryKey между таблицами в базе данных, например ForeignKey -> User.MembershipId PrimaryKey -> Aspnet_Roles.RoleId 2. Из файла ADO.NET (.edmx) обновите модель из базы данных, вы увидите, что в сущности User существует связь, созданная для сущности Aspnet_Roles 3. В XAML напишите приведенный ниже код, чтобы привязать поле со списком к желаемому полю формы данных.

<Combobox DisplayMemberPath="RoleName" SelectedItem="{Binding MembershipRoleId,Mode=TwoWay}" .... />
person Pankaj Awasthi    schedule 29.12.2011