【问题标题】:How to Bind a Listview to an observallable collection in a WCF service?如何将 Listview 绑定到 WCF 服务中的可观察集合?
【发布时间】:2018-07-19 04:38:05
【问题描述】:

我在 WPF 应用程序中托管 WCF 服务。 WCF 服务有一个 Observablecollection,我试图将其绑定到 WPF 中的列表视图,但由于初始化时列表为空,我不断收到 nullreference 异常。它仅在客户端连接到服务时添加元素。我的 XAML 在下面

<ListView HorizontalAlignment="Left" Height="341" Margin="42,35,0,0" VerticalAlignment="Top" Width="621" x:Name="listView">
        <ListView.View>
            <GridView>
                <GridViewColumn Header=" Time" Width="100" DisplayMemberBinding="{Binding Time}"/>
                <GridViewColumn Header="Blade Name" Width="200" DisplayMemberBinding="{Binding Name}"/>
            </GridView>
        </ListView.View>
    </ListView>

后面的代码的简化版本如下

using System.ServiceModel.Description;
using SomeNameSpace.WCFService;

namespace SomeNameSpace.WPFHost
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    ServiceHost host;
    MyClass SingleTonService;
    MyClass  srvc;
    public MainWindow()
    {

        try
        {             
            SingleTonService = new MyClass();
            host = new ServiceHost(SingleTonService, baseAddresses);             
            host.Open();

            var obj = host.SingletonInstance;

            srvc = (SomeNameSpace.WCFService.MyClass)obj;
            //WPF Section
            *** Getting null reference exception here since the list is emtpy ***
            listView.ItemsSource = srvc.__clientList;
            //Refresh();

        }
        catch(NullReferenceException e)
        {

        }
        catch (Exception e)
        {
            host.Abort();
        }
    }

简化的WCFService类如下

using System.Collections.ObjectModel;


namespace SomeNameSpace.WCFService
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                    ConcurrencyMode = ConcurrencyMode.Multiple,
                    UseSynchronizationContext = false)]
public class MyClass : IMyClass
{
    public ObservableCollection<Client> __clientList = new ObservableCollection<Client>();

    public ObservableCollection<Client> clientList
    { get { return __clientList; } }
    public ICallback Callback
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel<ICallback>();

        }
    }

    public bool Connect(Client client)
    {
        if (!clients.ContainsValue(CurrentCallback) && !SearchByName(client.Name))
        {
                __clientList.Add(client);
            }
            return true;
        }
        return false;
    }
 }

客户端类

[DataContract]
public class Client
{
    private string _name;
    private DateTime _time;

    [DataMember]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    [DataMember]
    public DateTime Time
    {
        get { return _time; }
        set { _time = value; }
    }
}

另外,如果我在调用 connect 方法后将 observablecollection 绑定到列表视图,则一切正常,因为列表不为空,但我无法在运行时执行此操作,因为我使用 buttonclick 事件和设置列表视图对此进行了测试。项目来源 在调用 connect 方法之后的事件中。最终代码中不会有任何按钮。

【问题讨论】:

    标签: wpf wcf data-binding observable


    【解决方案1】:

    分离是可观察集合仅在集合因添加或删除而更改时发送事件,而不是在其自身创建时发送事件。

    您真正想要做的是将列表框绑定到遵循INotifyPropertyChanged 的类(可能是视图模型)上的普通列表(或将其保留为可观察的集合),这将通知 XAML 有新的要显示的数据。绑定最好在 XAML 中完成。

    如何

    所以发生的情况是,当数据从网络中传入时,您会加载一个本地(在堆栈上)列表,直到收集到所有项目。然后在填充时将本地列表引用分配给视图模型上的列表。此时,Property changed 事件将触发,数据将显示给用户。


    我提供了一个可用于上述情况的 MVVM 示例。 Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding

    【讨论】:

    • 感谢您的回答。我找到了解决我的问题的方法。我是 WPF 的新手,我很确定有比我在这里做的更好的方法,但它现在有效:)
    【解决方案2】:

    我替换了下面的行

    listView.ItemsSource = srvc.__clientList;
    

    srvc.__clientList.CollectionChanged += OnCollectionChanged;
    

    在事件处理程序中,我使用下面的代码手动更新列表

    this.Dispatcher.Invoke((Action)(() =>
                {
                    listView.Items.Clear();
                    //update listview here
                }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-19
      • 2021-12-15
      • 2020-12-29
      • 1970-01-01
      • 2013-05-21
      • 2011-12-03
      • 1970-01-01
      • 2011-02-16
      相关资源
      最近更新 更多