【问题标题】:Callback not binding correctly回调未正确绑定
【发布时间】:2011-07-25 15:58:41
【问题描述】:

在下面的代码中,UnitOccupierDetails 集合正确绑定,但 OwnersCountString 没有。谁能解释为什么?这段代码在我的 ViewModel 中:

private void BindSelectedStructure(object param) 
    { 
        UnitOccupierDetails.Clear(); 
        Structure selectedStructure = (Structure)param; 
        this.SelectedStructure = selectedStructure; 

        int StructureID = selectedStructure.IDStructure; 
        loadOwners = context.Load<UserOccupier>(context.GetUnitOccupierDetailsQuery(StructureID), OwnersLoadedCallback, false); 
    } 

    private void OwnersLoadedCallback(LoadOperation<UserOccupier> op) 
    { 
        int Counter = 0; 
        foreach (var item in op.Entities) 
        { 
            Counter++; 
            UnitOccupierDetails.Add(item as UserOccupier); 
        } 

        OwnersCountString = "Owners(" + Counter.ToString() + ")"; 
    }

还有 XAML:

     <TextBlock Text='{Binding OwnersCountString,Source={StaticResource ViewModel},Mode=OneWay}'></TextBlock

OwnersCountStringProperty:

private string _ownersCountString;
    public string OwnersCountString
    {
        get { return _ownersCountString; }
        set { _ownersCountString = value; RaisePropertyChanged("OwnersCountString"); }
    }

【问题讨论】:

  • 又是一条评论。 (说真的,请尝试为您的问题提供更具描述性的标题。它们不会全部按顺序出现,因此很难从主页知道问题的内容。)
  • 那不是 MVVM,public string OwnersCountString {get;set;} 不会像你期望的那样工作。此外,这也是 UI 的问题,应该使用绑定中的转换器和/或 StringFormat 来处理。哦,你应该检查命名的框架指南。另外,请原谅我没有让这看起来很有帮助。
  • 点科迪。威尔,我发布的代码显然只是MVVM的一部分。 OwnerCountString 根据需要引发属性更改事件。 BindSelectedStructure 是 ICommand 调用并且运行良好。唯一不起作用的是设置 STRING 属性。那不应该需要转换器吗?即使我使用纯字符串(没有 Counter.ToString()),绑定也不起作用。
  • 请查看我更新的代码帖子,其中显示了属性代码。
  • 威尔,你有没有机会添加意见或建议,或者你完成了吗?

标签: silverlight silverlight-4.0 mvvm


【解决方案1】:

您的回调未在 UI 线程上发生。这意味着更改正在发生,但 UI 并未在显示更改的线程上自行更新。

这是来自another of my answers 的示例。我们的SendPropertyChanged 版本(替换您的RaisePropertyChanged)确保所有代码都在UI 线程上执行:

protected delegate void OnUiThreadDelegate();

public event PropertyChangedEventHandler PropertyChanged;

public void SendPropertyChanged(string propertyName)
{
    if (this.PropertyChanged != null)
    {
        this.OnUiThread(() => this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
    }
}

protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate)
{
    if (Deployment.Current.Dispatcher.CheckAccess())
    {
        onUiThreadDelegate();
    }
    else
    {
        Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate);
    }
}

【讨论】:

  • 高科,感谢您的回复。我怀疑这可能与线程有关。我应该如何去测试线程。这最好用 Fiddler 完成吗?
  • Fiddler 与 Silverlight 线程无关。它显示与浏览器之间的数据通信。您只需要知道某些操作不会在 UI 线程上回调(因此始终在 UI 线程上调用属性更改事件更安全)。
  • 好的——最后一个问题。如果我的 OwnersLoadedCallback 在 UI 线程上,UnitOccupierDetails 集合如何正确更新?是我在该方法中设置了另一个属性(OwnerCountString)并且 UI 线程忙于 OwnersOccupierDetails?对不起,线程对我来说是新的:-)
  • 我只能猜测集合事件会导致随后呈现的控件状态发生更显着的变化(文本块非常愚蠢)。我想我唯一的问题是:修复在您的特定实例中有效吗?
  • 我在 ViewModelBase 中实现了您的代码,并将 RaisePropertyChanged 更改为 SendPropertyChanged,但不幸的是它没有解决问题。在 SendPropertyChanged 方法中,this.PropertyChanged 总是返回 null。
猜你喜欢
  • 1970-01-01
  • 2019-11-30
  • 2010-12-18
  • 2013-12-05
  • 2016-12-28
  • 1970-01-01
  • 2018-05-18
  • 2014-02-05
  • 2013-08-11
相关资源
最近更新 更多