如何在WPF中将ObservableCollection与Listbox绑定 [英] How to bind ObservableCollection with Listbox in WPF

查看:107
本文介绍了如何在WPF中将ObservableCollection与Listbox绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在WPF应用程序中将ObservableCollectionListbox绑定.因此,当ObservableCollection中的元素将被修改时,ListBox将会自我更新.

I would like to bind ObservableCollection with Listbox in WPF application. So when elements in the ObservableCollection will be modified the ListBox will update itself.

类相机

ListBox在类MainWindow.xaml

我尝试过,但是不起作用:

I tried that, but it does not work:

相机类别:

       using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace HomeSecurity {

    public class Camera : INotifyPropertyChanged {
        public static readonly Regex AxisMacPattern = new Regex("00408[Cc][a-zA-Z0-9]{6}");
        public string _IP;
        public string IP {
            get {
                return _IP;
            }
            set {

                if (_IP != value) {
                    _IP = value;
                    OnPropertyChanged("IP");
                }

            }
        }
        public string _HTTPPort;
        public string HTTPPort {
            get {
                return _HTTPPort;
            }
            set {

                if (_HTTPPort != value) {
                    _HTTPPort = value;
                    OnPropertyChanged("HTTP");
                }

            }
        }
        public string _MAC;
        public string MAC {
            get {
                return _MAC;
            }
            set {

                if (_MAC != value) {
                    _MAC = value;
                    OnPropertyChanged("MAC");
                }

            }
        }
        public string _ServiceName;
        public string ServiceName {
            get {
                return _ServiceName;
            }
            set {

                if (_ServiceName != value) {
                    _ServiceName = value;
                    OnPropertyChanged("ServiceName");
                }

            }
        }
        public string _FullName;
        public string FullName {
            get {
                return _FullName;
            }
            set {

                if (_FullName != value) {
                    _FullName = value;
                    OnPropertyChanged("FullName");
                }

            }
        }
        public string _HostName;
        public string HostName {
            get {
                return _HostName;
            }
            set {

                if (_HostName != value) {
                    _HostName = value;
                    OnPropertyChanged("HostName");
                }

            }
        } 

        public Camera() { }
        public Camera(string MAC) : this(null, null, MAC, null, null, null) { }
        public Camera(string MAC, string ServiceName) : this(null, null, MAC, ServiceName, null, null) { }
        public Camera(string IP, string HTTPPort, string MAC, string ServiceName, string FullName, string HostName) {
            this.IP = IP;
            this.HTTPPort = HTTPPort;
            this.MAC = MAC;
            this.ServiceName = ServiceName;
            this.FullName = FullName;
            this.HostName = HostName;
            AddToExtension(this);
        }
        public static ObservableCollection<Camera> _extension = new ObservableCollection<Camera>();
        //

        public ObservableCollection<Camera> extension {
            get { return _extension; }
            set {
                if (_extension != value) {
                    _extension = value;
                    OnPropertyChanged("extension");
                }

            }
        }
        private void OnPropertyChanged(string propertyName) {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion


        // 

        public static void AddToExtension(Camera camera) {
            _extension.Add(camera);
        }

        public static void RemoveFromExtension(Camera camera) {
            _extension.Remove(camera);
        }

        public static Camera GetFromExtension(String MAC) {
            foreach (Camera camera in _extension)
                if (camera.MAC.Equals(MAC))
                    return camera;
            return null;
        }

        public static void PrintExtension() {
            foreach (Camera camera in _extension)
                Console.WriteLine(camera);
        }

        public override string ToString() {
            return "IP: " + IP + " HTTP Port: " + HTTPPort + " MAC: " + MAC + " Service Name: " + ServiceName + " FullName: " + FullName + " HostName: " + HostName;
        }
    }
}

XAML:

  <Window x:Class="HomeSecurity.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:HomeSecurity" 
        Title="MainWindow" WindowState="Maximized" Loaded="Window_Loaded"

        >

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="8*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="1366" />
        </Grid.ColumnDefinitions>
        <Border BorderBrush="Red" BorderThickness="4" Grid.Column="1" Grid.Row="0">
            <ListBox x:Name="CameraListBox"
         ItemsSource="{Binding Path=Camera.extension}">
                <ListBox.Resources>
                    <DataTemplate DataType="{x:Type local:Camera}">
                        <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5">
                           <TextBox Text="Hello World" /> 
                        </Border>
                    </DataTemplate>
                </ListBox.Resources>
            </ListBox>
        </Border>

        <Border BorderBrush="Green" BorderThickness="2" Grid.Column="1" Grid.Row="1">
            <ScrollViewer >
                <WrapPanel x:Name="VideoPanel" >
                </WrapPanel>
            </ScrollViewer>
        </Border>


    </Grid>

</Window>

MainWindow.xaml.cs:

MainWindow.xaml.cs:

using Bonjour;

namespace HomeSecurity {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged {

        public MainWindow() {
            DataContext = this;
            InitializeComponent();

        //   this.DataContext = this;
        }
       //
        private Camera _camera;
        public Camera Camera
        {
            get { return _camera; }
            set
            {
                if (_camera != value)
                {
                     _camera= value;
                     OnPropertyChanged("Camera");
                }

            }
        }

        /// <summary>
        /// Raises the PropertyChanged notification in a thread safe manner
        /// </summary>
        /// <param name="propertyName"></param>
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
        //
        private void Window_Loaded(object sender, RoutedEventArgs e) {
            createGUI();
        }

        private void createGUI() {
            Console.WriteLine("dupa");
            Scanner.ScanService();
      //      startListening();
            //THIS CODE WON'T RUN BECAUSE   Scanner.ScanService(); have frozen it
            AddVideoStream("192.168.0.2");
            AddVideoStream("192.168.0.2");
            AddVideoStream("192.168.0.2");
        }

        private void startListening() {
            Camera._extension.CollectionChanged += (s, e) => {
             //  CameraListBox.Items.Add(Camera.extension.Last());
            };
        }


        //TEN
        private void AddVideoStream(String sourceIP) {
            int cols = 2;
            int formsHostWidth = (int)(VideoPanel.ActualWidth / cols) - 4;

            WindowsFormsHost formsHost = new WindowsFormsHost();
            VideoStream videoStream = new VideoStream(sourceIP);
            formsHost.Width = formsHostWidth;
            formsHost.Height = videoStream.GetPrefferedHeight(formsHostWidth);
            formsHost.Child = videoStream;
            Border lineBorder = new Border();
            lineBorder.BorderBrush = Brushes.Green;
            lineBorder.BorderThickness = new Thickness(2);
            lineBorder.Child = formsHost;
            VideoPanel.Children.Add(lineBorder);

        }
    }
}

如果我将MAinWindow.xaml.cs中的构造函数更改为:

If I change constructor in MAinWindow.xaml.cs to:

  InitializeComponent();
            Camera = new Camera();
            DataContext = this;

我得到:

但这不是更新的数据...这是在扩展中插入Camera对象时的数据.

but this is not updated data... it is data frome the time where the Camera object was inserted in the extension.

推荐答案

除非您确实希望在类的所有实例之间共享,否则不要使用静态属性.

You don't want to use a static property unless you really want to be shared between all instances of your class.

初始化UI时,扩展名将为null.因此,绑定将设置为null,并且不会发生任何事情.您需要做的是让您的UI知道扩展区何时更新,以便它可以侦听何时添加新对象.这有道理吗?

When your UI is initialized extension will be null. So the binding will be setup to null and nothing will happen. What you need to do is let your UI know when extention is updated, so it can listen for when new objects are added. Does that make sense?

在上面的示例中,创建扩展名时,该属性未调用PropertyChangedEventArgs,因此它实际上并未在监听您的收藏集.

Your example above, the property is not calling PropertyChangedEventArgs when extension is created so it is not actually listening to your collection.

public class Camera : INotifyPropertyChanged
{
        private ObservableCollection<Camera> _extension;
        public ObservableCollection<Camera> extension;
        {
            get { return _extension; }
            set
            {
                if (_extension != value)
                {
                     _extension= value;
                     OnPropertyChanged("extension");
                }

            }
        }

        /// <summary>
        /// Raises the PropertyChanged notification in a thread safe manner
        /// </summary>
        /// <param name="propertyName"></param>
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

}

还将其添加到构造函数DataContext = this中,并在您的窗口类中实现INotifyPropertyChanged.像这样

Also add this to your constructor DataContext = this, and implement INotifyPropertyChanged in your window class also. Something like this

public partial class MainWindow : Window, INotifyPropertyChanged
{
        public MainWindow() {
            DataContext = this;
            InitializeComponent();
        }

        // ... 

        private Camera _camera;
        public Camera Camera;
        {
            get { return _camera; }
            set
            {
                if (_camera != value)
                {
                     _camera= value;
                     OnPropertyChanged("Camera");
                }

            }
        }

        /// <summary>
        /// Raises the PropertyChanged notification in a thread safe manner
        /// </summary>
        /// <param name="propertyName"></param>
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
}

我认为您也需要一个数据模板才能显示某些内容

I think you need to have a data template for something to show up too

<ListBox x:Name="CameraListBox"
         ItemsSource="{Binding Path=Camera.extension}">
    <ListBox.Resources>
        <DataTemplate DataType="{x:Type local:Camera}">
            <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5">
                <TextBox Text="Hello World" />
            </Border>
        </DataTemplate>
    </ListBox.Resources>
</ListBox>

这篇关于如何在WPF中将ObservableCollection与Listbox绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆