2
votes

I have this problem, I've got Silverlight app written using MVVM. I need to create DataForm which is binded to property on ViewModel and I want to add ComboBox and fill it with values from other collection in the same ViewModel.

Code:

<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>

All this is handled by NewAccountVM which has these properties:

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");
            }
        }
    }

Now, all this works besides adding ItemsSource to ComboBox. I've found many examples showing how fill CB in CodeBehind, but like I said I want to do this in MVVM-Style :) I understand that, ComboBox inherited DataContext from DataForm, and this ItemsSource="{Binding Path=Languages, Mode=TwoWay}" will not work, but I have no idea how to achieve my goal.

Can somebody help me?

3

3 Answers

6
votes

1) Declare the viewmodel to the view in the resources section.

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

2) Bind the ComboBox to the collection property on the viewmodel.

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

you can set the Data Context in XAML to your static resource like so:

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

Scenario A: 1. Assume you wish to populate a combo with all the membership Roles, and allow the client to select the role and assign to the User : i.e. ObjectA : Aspnet_Role i.e. ObjectB : User

  1. Let us say User.MembershipRoleId is to be bound to Aspnet_Role.RoleId

  2. Dataform is bound to ObjectB

  3. Combobox in dataform is populated with List
  4. In XAML write the following:

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

here the mapping is, ObjectB.MembershipRoleId=ObjectA.RoleId

Scenario B: 1. If you do not want to explicitly define by the way in ScenarioA, then in that case, define a ForeignKey-PrimaryKey relationship between the tables in the database like ForeignKey -> User.MembershipId PrimaryKey -> Aspnet_Roles.RoleId 2. From the ADO.NET (.edmx) file, update the model from the database, you will observe that in the User entity there is an association made upon entity Aspnet_Roles 3. In XAML write the code as below to bind the combobox, to the desired field of the Dataform

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