【问题标题】:Databinding 2 comboboxes Issue数据绑定 2 组合框问题
【发布时间】:2013-02-01 16:47:18
【问题描述】:

我有 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。 我搜索了很多以寻求帮助,但我找不到任何东西。 如果有人可以在代码中指定任何问题,我将非常高兴。

【问题讨论】:

  • 我也为此苦苦挣扎了一段时间

标签: wpf data-binding combobox viewmodel


【解决方案1】:

不要绑定到组合框中的 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 正在管理列表并且知道所选项目是哪个,则适用)。

希望对您有所帮助!问候

【讨论】:

  • Hannish,谢谢你的帮助,但它仍然没有解决我的问题,当我打开第二个组合框时,我仍然看到空列表。
  • 我看到您在第二个组合框中设置了 DisplayMemberPath="SubActivityname"... 您确定拼写正确吗? XAML 区分大小写并且没有智能感知帮助,所以可以尝试“SubActivityName”吗?如果您在打开组合时可以看到许多空白项,您仍然可以判断您的绑定是否有效,与子活动的数量相同。
  • 第二个组合框名称正确。当我打开第二个组合框时,我看到所有活动的空白项目数量相同。
  • 我看到了许多项目,只是您没有显示正确的属性,但对象在那里。尝试显示 ID,然后再次检查拼写以防万一。你快搞定了!
  • 我已经验证了一切,所有的属性名和列名,它们看起来都很好。不知道为什么仍然存在问题。但是,如果我单击其他行的另一个单元格,则会为在第一个组合框中选择 Activity 的所有行填充第二个组合框的相应子活动。
【解决方案2】:

我解决了我的问题。 当一个活动发生变化时,应该通知相关的子活动变化。 但是当Sub-Activity发生变化时不需要通知Activity。

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

private int currentSubActivity;

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

        }
    }

我希望这对那里的人也有帮助:)

【讨论】:

  • 也许这对你有用,但我不认为这是一个对其他人有帮助的通用答案。如果删除 OnPropertyChanged 调用,视图将无法知道属性已更改,这也破坏了 MVVM 模式。如果 UI 更新正常,请确保您在其他地方发出通知。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多