【问题标题】:Silverlight bind collection to Combobox in DataForm using MVVMSilverlight 使用 MVVM 将集合绑定到 DataForm 中的 Combobox
【发布时间】:2010-12-21 16:50:38
【问题描述】:

我有这个问题,我有使用 MVVM 编写的 Silverlight 应用程序。我需要创建绑定到 ViewModel 上的属性的 DataForm,我想添加 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 之外,所有这些都可以正常工作。我发现了很多例子,展示了如何在 CodeBehind 中填充 CB,但就像我说的那样,我想在 MVVM-Style 中做到这一点:) 我知道,ComboBox 从 DataForm 继承了 DataContext,这个 ItemsSource="{Binding Path=Languages, Mode=TwoWay}" 不起作用,但我不知道如何实现我的目标。

有人可以帮帮我吗?

【问题讨论】:

    标签: silverlight data-binding mvvm combobox dataform


    【解决方案1】:

    1) 将视图模型声明到资源部分中的视图。

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

    2) 将 ComboBox 绑定到 viewmodel 上的集合属性。

    <ComboBox ItemsSource="{Binding Path=Languages, 
                                    Source={StaticResource myViewModel}, 
                                    Mode=TwoWay}"/>
    

    【讨论】:

    • 谢谢,就是这样 :) 我发现它更危险,但我的 ViewModel 有问题,因为它有 2 个构造函数,我不得不用静态资源将 ViewModel 的创建重新组织到这个.再次感谢。
    • 在这个例子中,你在哪里将 ViewModel 设置为 UserControl 的 DataContext?我假设您在 UserControl 的构造函数中这样做,但我想确定。
    • @michajas 在资源内部设置虚拟机时要小心,如果您的虚拟机 ctor 抛出异常,它将被 XAML 解析错误吞噬。我强烈建议在 Loaded 事件中设置 VM 并使用 IoC 容器,以获得更大的灵活性。
    【解决方案2】:

    您可以将 XAML 中的数据上下文设置为您的静态资源,如下所示:

    <UserControl.DataContext>
        <Binding Source="{StaticResource myViewModel}" />
    </UserControl.DataContext>
    

    【讨论】:

      【解决方案3】:

      场景 A: 1.假设您希望使用所有成员角色填充一个组合,并允许客户端选择角色并分配给用户: 即 ObjectA : Aspnet_Role 即 ObjectB :用户

      1. 假设 User.MembershipRoleId 将绑定到 Aspnet_Role.RoleId

      2. Dataform 绑定到 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 中编写如下代码将组合框绑定到 Dataform 的所需字段

      <Combobox DisplayMemberPath="RoleName" SelectedItem="{Binding MembershipRoleId,Mode=TwoWay}" .... />
      

      【讨论】:

        猜你喜欢
        • 2011-06-29
        • 2011-02-28
        • 2016-06-17
        • 2019-10-11
        • 2013-12-17
        • 1970-01-01
        • 2016-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多