【发布时间】:2014-01-15 03:35:47
【问题描述】:
我想在 WPF 应用程序中将ObservableCollection 与Listbox 绑定。因此,当 ObservableCollection 中的元素被修改时,ListBox 将自行更新。
相机类
中有一个public static ObservableCollection<Camera> extension = new ObservableCollection<Camera>();
ListBox 属于 MainWindow.xaml 类
我试过了,还是不行:
相机类:
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:
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 中的构造函数更改为:
InitializeComponent();
Camera = new Camera();
DataContext = this;
我明白了:
但这不是更新的数据...它是相机对象插入扩展时的数据。
【问题讨论】:
-
您可以尝试添加一个虚拟对象并立即将其删除。但我不确定你到底想要完成什么?您是否考虑过将您的 UI 绑定到集合中各个对象的 INotifyPropertyChange?
-
只需将ListBox的ItemSource设置为你的ObservableCollection,它会在添加/删除项目时监听。
-
<ListBox x:Name="CameraListBox" ItemsSource="{Binding Path=Camera.extension}">呢?假设您的 DataContext 是正确的。我认为这是正确的语法,但不是在我的工作电脑上。 -
Camera 是否实现 INotifyPropertyChanged(和扩展属性)?如果不是,您将绑定到一个空值,并且在创建可观察集合并将其分配给扩展时,您的 UI 永远不会更新。
-
您需要实现它(或在
InitalizeComponent()之前设置它)- 请参阅我在这篇文章中的回答-stackoverflow.com/questions/20664707/…
标签: c# events observablecollection