Silverlight 绑定不能动态工作


我是 Silverlight

新手,我无法使简单的 Silverlight 绑定示例工作!

我需要制作一个视图模型,在加载时显示列表中的文档数量。

我做了一个基类,它实现了INotifyPropertyChanged:

public abstract class BaseViewModel : INotifyPropertyChanged {
    protected BaseViewModel() {}

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

我创建了一个具有"CountDocs"属性的子类:

public class DocumentViewModel : BaseViewModel {
    public DocumentViewModel () {
    ...
    }
...
    public int CountDocs {
        get { return countDocs; }
        set {
            if (countDocs != value) {
                countDocs = value;
                OnPropertyChanged("CountDocs");
            }
        }
    }
    public int countDocs;
}

我有 DocumentViewModel.xaml 包含以下内容:

<UserControl 
...
xmlns:vm="clr-namespace: ... .ViewModels" >
...
<UserControl.Resources>
    <vm:DocumentViewModel  x:Key="viewModel"/>
</UserControl.Resources>
...
<TextBlock x:Name="CounterTextBlock" Text="{Binding Source={StaticResource viewModel}, Path=CountDocs}"></TextBlock>
也就是说,我提到了我的子类

的命名空间,我用键"viewModel"制作了我的子类的资源,并将文本块绑定到这个对象的属性"CountDocs"。

问题是 CountDocs 属性只填充一次文本块:加载时。但是后来我设置了CountDocs,它没有填充TextBlock。

我尝试使用绑定的 Mode 属性来使用 DataContext,但我仍然无法使其工作。

绑定有问题吗?如何使视图模型在对象的 CountDocs 属性发生更改时进行更新?

谢谢

好的,

因为你在 XAML 中创建了 ViewModel 实例,因此需要访问和使用该 ViewModel。

如果有另一个实例,该实例不会更新绑定。 只会使用在资源中创建的实例。

现在你说你设置了 CountDocs 属性,但我没有看到任何代码。 无论在哪里执行此操作,都必须使用资源中的 ViewModel 实例。

这就是为什么我喜欢在我的视图构造函数中实例化我的视图模型并保留对它的引用。 此外,除非您计划将许多数据源附加到绑定,否则只需将 LayoutRoot.DataContext 设置为 ViewModel 实例,并删除绑定中的 Source 属性。

视图模型库 _vm = 空;
公共我的视图()

{ _vm = new DocumentViewModel();
这。LayoutRoot.DataContext = _vm;
}

在 XAML 中, <TextBlock x:Name="CounterTextBlock" Text="{Binding CountDocs}"></TextBlock>

如果我了解您的问题的详细信息,您可能正在更新后台线程上的 UI 绑定值(在文档加载时)。

您需要在 UI 线程上执行此操作,否则更改将不可见。在我们的一个 WPF 应用程序中,随机更新正在消失,直到我们意识到这一点。

我们在 Silverlight(和 WPF)应用程序中执行了大量多线程操作,因此为了避免此问题,我们在如下所示的基类中实现了通知帮助程序(其他内容已剪掉)。它调度主 UI 线程上的所有通知消息。试一试:

public class ViewModelBase : INotifyPropertyChanged
{
    protected delegate void OnUiThreadDelegate();
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void SendPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            // Ensure property change is on the UI thread
            this.OnUiThread(() => this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
        }
    }
    protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate)
    {
        // Are we on the Dispatcher thread ?
        if (Deployment.Current.Dispatcher.CheckAccess())
        {
            onUiThreadDelegate();
        }
        else
        {
            // We are not on the UI Dispatcher thread so invoke the call on it.
            Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate);
        }
    }
}

正如我们在对您的问题的评论中发现的那样,您的 ViewModel 实例化了两次,并更改了实际上未绑定到视图的属性值。

这怎么可能?您要么使用自动将 ViewModels 连接到视图的 MVVM 框架,要么它发生在代码中您不知道的某个位置。在构造函数中放置一个断点,当它命中时,在 Visual Studio 中分析调用堆栈。

最新更新