2014-11-06 111 views
0

我目前正在嘗試理解MVVM的概念。因此,我已經閱讀了幾個博客,並看了幾個項目。但是,我仍然不知道如何應用這個概念。在WPF中將一個ObservableCollection字符串綁定到列表框

現在,我試圖將一個ObservableCollection的String值綁定到一個ListBox,以便它們的值逐行列出。我視圖模型目前看起來是這樣的:

namespace TestApp.ViewModel 
{ 
    class StatusViewModel : NotifyPropertyChanged 
    { 
     private string _newMsg; 
     private readonly ObservableCollection<string> _history = new ObservableCollection<string>(); 

     public string Print 
     { 
      get { return _newMsg; } 
      set 
      { 
       _newMsg = value; 
       RaisePropertyChangedEvent("History"); 
       AddToHistory(_newMsg); 
      } 
     } 

     public IEnumerable<string> History 
     { 
      get { return _history; } 
     } 

     private void AddToHistory(string item) 
     { 
      if (!_history.Contains(item)) 
       _history.Add(item); 
     } 
    } 
} 

namespace TestApp.ViewModel 
{ 
    public class NotifyPropertyChanged : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

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

在視圖中,我要到ListBox綁定到History。這是我的XAML:

<UserControl x:Class="TestApp.View.StatusView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:vm="clr-namespace:TestApp.ViewModel" mc:Ignorable="d"> 
    <UserControl.Resources> 
     <vm:StatusView x:Key="statusView"/> 
    </UserControl.Resources> 
    <Grid DataContext="{StaticResource statusView}"> 
     <GroupBox Header="StatusView"> 
      <ListBox x:Name="StatusListBox" ItemsSource="{Binding History, Source={StaticResource statusView}}"/> 
     </GroupBox> 
    </Grid> 
</UserControl> 

當我開始TestApp,我需要訪問我StatusViewModel的情況下,以一個字符串添加到我的ObservableCollection。我想知道如何做到這一點:

using TestApp.ViewModel; 

namespace TestApp.Controller 
{ 
    public partial class Startup 
    { 
     private void StartTestApp() 
     { 
      // from where do I get my 'statObj' in order to do: 
      statObj.Print = "something"; 
     } 
    } 
} 

如何字符串的ObservableCollection綁定在我StatusViewModel對象列表框?

UPDATE:

謝謝大家對偉大的意見!現在,我知道我需要保存我的ViewModel的一個實例,以便從查看控制器訪問它。然而,我仍然在努力如何以正確的方式做到這一點##標題#

現在,我開始在用戶控件的代碼隱藏中創建實例。雖然它正在工作,但我不喜歡我必須在View中引用ViewModel。我想,這是MVVM 而不是這一點。此外,我想知道如何在視圖外部訪問我新近實例化的StatusViewModel狀態,例如,在名爲的控制器

using System.Windows.Controls; 
using TestApp.ViewModel; 

namespace TestApp.View 
{ 
    /// <summary> 
    /// Interaction Logic for StatusView.xaml 
    /// </summary> 
    public partial class StatusView : UserControl 
    { 
     public StatusView() 
     { 
      InitializeComponent(); 

      this.DataContext = new StatusViewModel(); 
     } 

     public TestApp.ViewModel.StatusViewModel State 
     { 
      get { return (DataContext as TestApp.ViewModel.StatusViewModel); } 
     } 
    } 
} 
+1

綁定上Status'的'這種情況下將工作:' '並且爲了測試你創建**不同的'Status'實例**並且改變'Print'。它們不是同一個對象 – dkozl 2014-11-06 14:43:41

+0

這很合理!但是我怎麼能在我的'StartTestApp'方法中編輯存在的狀態對象呢?我的start方法位於不同的命名空間中,名稱爲'TestApp.Controller'。 – berti 2014-11-06 14:46:26

+0

您需要掌握該實例。取決於你的設計。有些人使用包含視圖模型定位器的框架。我通常將我的虛擬機定義爲app.xaml中的資源,然後*將它們綁定到對方*,因此VM X具有對VM Y的引用。有些人在視圖的構造函數中構造它們,以便它們引用它。隨你怎麼便。 – Will 2014-11-06 15:07:42

回答

0

您的XAML改成這樣:

<UserControl x:Class="TestApp.View.Status" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:vm="clr-namespace:TestApp.ViewModel" mc:Ignorable="d"> 
<UserControl.DataContext> 
    <vm:Status /> 
</UserControl.DataContext> 
<Grid> 
    <GroupBox Header="Status"> 
     <ListBox x:Name="StatusListBox" ItemsSource="{Binding History}"/> 
    </GroupBox> 
</Grid> 

並訪問您的viemodel應該包含這樣的代碼:

Status status = DataContext as Status; 
if (status != null) 
    status.Print = "Hello"; 

然後它似乎工作: enter image description here

當你想訪問該用戶控件的狀態情況下,將屬性添加到用戶控件:

public TestApp.ViewModel.Status State // Status gives probably naming conflict 
{ 
    get 
    { 
     return (DataContext as TestApp.ViewModel.Status); 
    } 
} 
+0

感謝您的快速回答!不幸的是,我的ListBox中仍然沒有顯示任何消息:( – berti 2014-11-06 14:35:40

+0

)您還沒有設置DataContext。哦,您確實...對不起。 – Sjips 2014-11-06 14:39:00

+0

我應該在哪裏添加if(DataContext!= null)...? – berti 2014-11-06 15:02:47

0

嘗試

public ObservableCollection<string> History 
{ 
    get { return _history; } 
} 
private void AddToHistory(string item) 
{ 
    if (!History.Contains(item)) History.Add(item); 
} 
相關問題