簡體   English   中英

將字符串的ObservableCollection綁定到WPF中的列表框

[英]Binding an ObservableCollection of Strings to a ListBox in WPF

我目前正在嘗試掌握MVVM的概念。 因此,我已經閱讀了幾個博客,並研究了一些項目。 但是,我仍然不知道如何應用該概念。

現在,我嘗試將String值的ObservableCollection綁定到ListBox,以便將它們的值逐行列出。 我的ViewModel當前如下所示:

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";
        }
    }
}

如何將StatusViewModel對象中的字符串的ObservableCollection綁定到列表框?

更新:

謝謝大家的好評! 現在,我知道我需要持有ViewModel的實例,以便從View Controller都可以訪問它。 但是,我仍在努力以正確的方式進行操作。##標題##

現在,我首先在用戶控件的代碼背后創建實例。 盡管它可以正常工作,但我不喜歡在視圖中引用ViewModel。 我認為,這不是 MVVM的全部重點。

而且,我想知道如何在View外部訪問新實例化的StatusViewModel狀態,例如在另一個名為Controller的命名空間中。

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); }
        }
    }
}

將您的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";

然后它似乎起作用: 在此處輸入圖片說明

當您要訪問此用戶控件的Status實例時,請向該用戶控件添加一個屬性:

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

嘗試

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM