【问题标题】:WPF ComboBox Binding To Object On Initial LoadWPF ComboBox 在初始加载时绑定到对象
【发布时间】:2011-07-16 22:36:02
【问题描述】:

我有一个绑定到模型对象列表的组合框。我已将组合框 SelectedItem 绑定到模型类型的属性。加载窗口后,我的所有数据绑定都可以正常工作。 SelectedItem 设置正确,我可以直接使用存储库保存对象。

问题是当窗口第一次加载时,我初始化了 SelectedItem 属性,而我的组合框什么也不显示。在我开始绑定到对象之前,我绑定到了一个字符串列表,并且在初始化时效果很好。我知道我错过了一些东西,但我无法弄清楚。

提前感谢您提供的任何指导。

(关于此页面布局的一个注意事项。组合框实际上是 ListView 中使用的另一个 ItemTemplate 的一部分。ListView 绑定到主 MV 中的一个可观察集合。这个可观察集合的每个项目都是它自己一个 ModelView。它是具有 SelectedItem 属性的第二个 ModelView。)

这是我的模型:

    public class DistributionListModel : Notifier, IComparable
    {
    private string m_code;
    private string m_description;

    public string Code
    {
        get { return m_code; }
        set { m_code = value; OnPropertyChanged("Code"); }
    }

    public string Name
    {
        get { return m_description; }
        set { m_description = value; OnPropertyChanged("Name"); }
    }

    #region IComparable Members

    public int CompareTo(object obj)
    {
        DistributionListModel compareObj = obj as DistributionListModel;
        if (compareObj == null)
            return 1;

        return Code.CompareTo(compareObj.Code);
    }

    #endregion
}

这里是我的 ModelView 中的相关代码:

public MailRoutingConfigurationViewModel(int agencyID)
    : base()
{
    m_agencyID = agencyID;
    m_agencyName = DataManager.QueryEngine.GetAgencyName(agencyID);

    IntializeValuesFromConfiguration(DataManager.MailQueryEngine.GetMailRoutingConfiguration(agencyID));

    // reset modified flag
    m_modified = false;
}

private void IntializeValuesFromConfiguration(RecordCheckMailRoutingConfiguration configuration)
{
    SelectedDistributionList = ConfigurationRepository.Instance.GetDistributionListByCode(configuration.DistributionCode);
}

public DistributionListModel SelectedDistributionList
{
    get { return m_selectedDistributionList; }
    set
    {
        m_selectedDistributionList = value;
        m_modified = true;
        OnPropertyChanged("SelectedDistributionList");
    }

}

最后是相关的 XAML:

<UserControl.Resources>
        <DataTemplate x:Key="DistributionListTemplate">
            <Label Content="{Binding Path=Name}" />
        </DataTemplate>
</UserControl.Resources>
              <ComboBox 
                       ItemsSource="{Binding Source={StaticResource DistributionCodeViewSource}, Mode=OneWay}"
                       ItemTemplate="{StaticResource DistributionListTemplate}"
                                        SelectedItem="{Binding Path=SelectedDistributionList, Mode=TwoWay}"
                        IsSynchronizedWithCurrentItem="False"
                                         />

【问题讨论】:

    标签: c# wpf data-binding mvvm combobox


    【解决方案1】:

    @SRM,如果我理解正确,您的问题是将您的组合框绑定到对象集合而不是值类型的集合(如字符串或 int- 尽管字符串不是值类型)。 我建议在您的组合框上再添加两个属性

    <ComboBox 
      ItemsSource="{Binding Source={StaticResource DistributionCodeViewSource}, 
                            Mode=OneWay}"                        
      ItemTemplate="{StaticResource DistributionListTemplate}"
      SelectedItem="{Binding Path=SelectedDistributionList, Mode=TwoWay}"
      SelectedValuePath="Code"  
      SelectedValue="{Binding SelectedDistributionList.Code }"/>
    

    我在这里假设 DistributionListModel 对象由它们的代码标识。 我添加的两个属性 SelectedValuePath 和 SelectedValue 帮助组合框通过组合框内的弹出控件识别用于标记选择 ComboBoxItem 的属性。 ItemSource 使用 SelectedValuePath,TextBox 使用 SelectedValue。

    【讨论】:

    • 这看起来也很有希望。您的假设是正确的,即我的 DistributionListModel 对象由它们的代码标识(事实上,最终持久化的是代码)。
    【解决方案2】:

    不要从构造函数调用你的IntializeValuesFromConfiguration,而是在加载视图之后。

    实现这一点的一种方法是在您的视图模型中创建一个运行此方法的命令,然后在加载的事件中调用该命令。 使用 MVVM 轻量级工具包,您可以使用 EventToCommand 行为...不知道您正在使用的 mvvm 框架,但可能会有这样的东西。

    【讨论】:

    • 它实际上是一个你自己的框架。我在听说 MVVM 工具包之前就开始了它。我创建的许多类都反映了 MVVM 工具包中的功能(解决同一问题的方法只有这么多),而且我的模式与工具包中使用的模式非常相似。例如,Notifier 与 DependencyObject 相同(我昨天刚学到的东西)。我认为你的想法是合理的,会试一试。谢谢!
    • @SRM:无论您使用自己的 Notifer 类还是 MVVM Light 工具包及其 ViewModelBase,使它工作的实际是 INotifyPropertyChanged...而不是依赖对象(它也实现了这个接口)。我没有看到在 Mvvm ViewModel 层中使用 DependencyObject 有任何用处
    • 是的,我知道。 DependencyObject 只是 INotifyPropertyChanged 的​​包装器。它具有调试支持以检查属性名称是否正确,但本质上它为您提供了可覆盖的 OnPropertyChanged。正是 Notifier 中的功能——因此得名“Notifier”:)。 INotifyPropertyChanged 也只是一个接口,而不是一个具体的类,所以如果我不想使用,我不必使用任何这些 - 我只是实现接口。剩下的就是让程序员的生活更轻松(并减少错误)。
    • 我强烈建议你看看 MVVM Light 工具包。我喜欢这个工具包的地方在于它的简单性。只有几门课,但我在 mvvm 应用程序中需要的一切。
    猜你喜欢
    • 2013-05-31
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 2013-04-18
    相关资源
    最近更新 更多