MVVM Light 绑定到 Observable 集合

Posted

技术标签:

【中文标题】MVVM Light 绑定到 Observable 集合【英文标题】:MVVM Light Binding to Observable Collection 【发布时间】:2012-04-27 12:23:54 【问题描述】:

我将 MVVM light 与 EF4 和 SQL CE 4 结合使用,但我的 observable 集合存在问题。我的应用程序不一定需要使用 mvvm 模式,但由于我需要 observablecollection 的好处,我决定学习如何集成它。我可以成功地将我的属性实体数据库链接到我的列表框并显示它们,我还可以将这些实体的一些属性链接到文本框,但是当我尝试通过在文本框中键入来更新这些属性时,我遇到了困难。这是我的文本框和列表框的 xaml 代码:

 <TextBox Text="Binding SaleTitle, ValidatesOnDataErrors=true, Mode=TwoWay"
  <ListBox Height="424" 
        Margin="24,80,0,0"             
        x:Name="listBoxProperties"
        VerticalAlignment="Top" 
        ItemTemplate="StaticResource propertySummaryTemplate"
        IsSynchronizedWithCurrentItem="True"  
        Width="216" BorderThickness="0" Background="x:Null"
        FontFamily="Segoe UI" 
        ItemsSource="Binding PropertyList"
        SelectedItem="Binding CurrentProperty, Mode=TwoWay"
        ScrollViewer.HorizontalScrollBarVisibility="Disabled"
        UseLayoutRounding="True" 
        HorizontalAlignment="Left" 
        ScrollViewer.VerticalScrollBarVisibility="Disabled" >          
    </ListBox>

这是我的 MainViewModel 的部分代码:

   private string _SaleTitle;
    public string SaleTitle
    
        get
        
            if (CurrentProperty != null)
                return CurrentProperty.SaleTitle;
            else
                return "";
        
        set
        
            _SaleTitle = value;
            RaisePropertyChanged("SaleTitle");
        
    



              private RelayCommand loadCommand;
    public ICommand LoadCommand
    
        get
        
            if (loadCommand == null)
                loadCommand = new RelayCommand(() => Load());
            return loadCommand;
        
    
    private void Load()
    
        PropertyList = new ObservableCollection<Property>((from property in entities.Properties.Include("Images")
                                                          select property));
        propertyView = CollectionViewSource.GetDefaultView(PropertyList);
        if (propertyView != null)
            propertyView.CurrentChanged += new System.EventHandler(propertyView_CurrentChanged);
        RaisePropertyChanged("CurrentContact");
        RaisePropertyChanged("SaleTitle");
        RaisePropertyChanged("Address");
        RaisePropertyChanged("AuctioneerName");
        RaisePropertyChanged("AgentName");
        RaisePropertyChanged("Price");
        RaisePropertyChanged("NextBid");
        RaisePropertyChanged("Status");
    


        void propertyView_CurrentChanged(object sender, System.EventArgs e)
    
        RaisePropertyChanged("CurrentContact");
        RaisePropertyChanged("SaleTitle");
        RaisePropertyChanged("Address");
        RaisePropertyChanged("AuctioneerName");
        RaisePropertyChanged("AgentName");
        RaisePropertyChanged("Price");
        RaisePropertyChanged("NextBid");
        RaisePropertyChanged("Status");
    

    private Property _CurrentProperty;
    public Property CurrentProperty
    
        get
        
            if (propertyView != null)
                return propertyView.CurrentItem as Property;
            return null;
        

        set
        
            _CurrentProperty = value;
            RaisePropertyChanged("CurrentProperty");
        
    


     public ObservableCollection<Property> PropertyList
    
        get
        
            return propertyList;
        

        set
        
            if (propertyList == value)
            
                return;
            

            var oldValue = propertyList;
            propertyList = value;

            // Update bindings, no broadcast
            RaisePropertyChanged(PropertiesPropertyName);
        
    

    public MainViewModel()
    
        if (IsInDesignMode)
        
            // Code runs in Blend --> create design time data.
        
        else
        
            // Code runs "for real"
            entities = new Model1Container1();
        
    

    ////public override void Cleanup()
    ////
    ////    // Clean up if needed

    ////    base.Cleanup();
    ////

列表框已成功填充当前所选项目的内容,但当我输入它并单击它或执行任何操作以失去焦点时,它只会回到之前的状态。

【问题讨论】:

【参考方案1】:

查看您的 SaleTitle 属性定义。它从 CurrentProperty.Saletitle 读取值,但将值设置为未在任何地方使用的本地字段。

【讨论】:

我发誓我已经试过了,简直不敢相信它是如此简单 - 一定是我连续 10 小时后在耍花招!

以上是关于MVVM Light 绑定到 Observable 集合的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF MVVM Light 中多次绑定到 RelayCommand

MVVM:将带有 Observable 集合的命令绑定到 Listbox 并从文本框中获取值

MVVM Light新手初识MVVM,你一看就会

MVVM Light新手初识MVVM,你一看就会

RxSwift 和 MVVM:observable 在没有绑定的情况下无法执行

MVVM Binding Observable Collection 来查看?