数据绑定2组合框问题

时间:2013-02-01 16:47:19

标签: wpf data-binding combobox viewmodel

我有2个组合框。如果我在第一个中选择一个活动,则相关的子活动应该显示在第二个组合框中。 根据MVVM样式,代码看起来很好,但是当我在第一个上选择一个活动时,第二个组合框中的相关子活动不会同步。 这是我的代码: 查看

<Window x:Class="TestDGCombosBinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestDGCombosBinding"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="ActivitiesDataProvider" ObjectType="{x:Type local:Activities}" MethodName="GetActivities"/>
        <local:DebugConverter x:Key="DebugConverter" />
    </Grid.Resources>
    <DataGrid 
        Grid.Row="1" Grid.Column="1" 
                 AutoGenerateColumns="False"                     
                 SelectionUnit="CellOrRowHeader"
                 SelectionMode="Single"
                 IsSynchronizedWithCurrentItem="True" 
                 RowBackground="White" 
                 AlternatingRowBackground="LightGray"                                          
                 AlternationCount="2" Name="dataGrid1" CurrentCellChanged="dataGrid1_CurrentCellChanged">
        <DataGrid.BindingGroup>
            <BindingGroup />
        </DataGrid.BindingGroup>
        <DataGrid.Resources>

        </DataGrid.Resources>

        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Activities Custom" CanUserSort="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Text="{Binding CurrentActivity}"                                       
                                    SelectedValuePath="ActivityID"                                        
                                    DisplayMemberPath="ActivityName"
                                    ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="SubActivities Custom" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Text="{Binding CurrentSubActivity}"                                       
                                    SelectedValuePath="SubActivityID"                                      
                                    DisplayMemberPath="SubActivityname"
                                    ItemsSource="{Binding Path=SubActivitiesOfCurrentActivity}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>
    </DataGrid>
</Grid>


模型

public class Activities
{
    public DataView GetActivities()
    {
        return ActivitiesAccess.GetAllActivities();
    }
}

视图模型

public class ActivitiesViewModel : INotifyPropertyChanged
{
    public ActivitiesViewModel()
    { }
    private int currentActivity;

    public int CurrentActivity
    {
        get { return currentActivity; }
        set { 
                currentActivity = value;
                SubActivitiesOfCurrentActivity = ActivitiesAccess.GetAllSubActivitiesinActivity(currentActivity);
                OnPropertyChanged("CurrentActivity");
            }
    }

    private DataView subActivitiesOfCurrentActivity;

    public DataView SubActivitiesOfCurrentActivity
    {
        get {return subActivitiesOfCurrentActivity; }
        set
        {
            subActivitiesOfCurrentActivity = value;
            OnPropertyChanged("SubActivitiesOfCurrentActivity");
        }
    }

    private int currentSubActivity;

    public int CurrentSubActivity
    {
        get { return currentSubActivity; }
        set
        {
            currentSubActivity = value;
            OnPropertyChanged("CurrentSubActivity");
            }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

当我从第一个下拉列表中选择活动时调试代码时,CurrentActivity属性值始终为0,我不知道为什么。 此值应等于所选活动的ActivityID。 我搜索了很多以获得帮助,但我找不到任何东西。 如果有人可以在代码中指明任何问题,我将非常高兴。

2 个答案:

答案 0 :(得分:0)

不要绑定到组合框中的Text属性,请尝试替换:

 <ComboBox Text="{Binding CurrentActivity}"                                       
                                SelectedValuePath="ActivityID"                                        
                                DisplayMemberPath="ActivityName"
                                ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"/>

使用:

<ComboBox ItemsSource="{Binding Source={StaticResource ActivitiesDataProvider}}"                                      
                                SelectedValuePath="ActivityID"                                        
                                DisplayMemberPath="ActivityName"
                                SelectedValue="{Binding CurrentActivity}"
                                IsSynchronizedWithCurrentItem="True"/>

子活动组合框的相同想法。通常,对于组合框,请使用SelectedItem和SelectedIndex属性。还可以使用IsSynchronizedWithCurrentItem(取决于ItemsSource的类型。

顺便说一句,如果你不想要,你不需要绑定到ID,你可以使用:

直接绑定到整个对象
 SelectedValue="{Binding SelectedItem}"

将组合框的值绑定到列表中的选定项目,只需使用IsSynchronizedWithCurrentItem =“True”与VM保持同步(如果您的VM正在管理列表并知道所选项目是)。

希望这对你有所帮助!此致

答案 1 :(得分:0)

我解决了我的问题。 更改活动时,应通知相关的子活动更改。 但是当子活动发生变化时,无需通知活动。

我刚在CurrentSubActivity属性中注释了OnPropertyChanged()调用。 这是代码

private int currentSubActivity;

    public int CurrentSubActivity
    {
        get { return currentSubActivity; }
        set
        {
            //OnPropertyChanged("CurrentSubActivity");
            this.currentSubActivity = value;

        }
    }

我希望这也可以帮助那些人:)