首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF DependencyProperty在WPF UserControl (ElementHost)中没有更新

WPF DependencyProperty在WPF UserControl (ElementHost)中没有更新
EN

Stack Overflow用户
提问于 2012-06-14 07:10:48
回答 2查看 1.3K关注 0票数 1

我构建了一个Office2010Word添加,在包含我的WPF的ElementHost对象中添加了一个Windows元素。

这就是问题所在:我遇到了问题,Xaml代码中定义并在ViewModel实现中设置的公共属性(DP)没有被更新,即使我在调试时找不到错误的代码。这只适用于我得到的属性,而且我得到了一些ObservableCollection<>列表,它们没有任何问题地被更新。有什么主意吗?我红色的意思是,我可以在代码中自己定义属性,如下所示:

代码语言:javascript
复制
public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource",typeof(string),typeof(usercontrol1));

但这也不起作用(例如,我只是将这一行添加到Xaml文件的代码隐藏文件中,并保留了其他任何内容)。

我的代码看起来是这样的:

Forms元素的构造函数(实际上是私有的,因为我将其实现为Singleton):

代码语言:javascript
复制
private Sidebar()
{
    InitializeComponent();
    this.DoubleBuffered = true;

    _wpfHost = new ElementHost();
    _wpfHost.Dock = DockStyle.Fill;

    _wpfUserControl = new WPFUI();

    _wpfHost.Child = _wpfUserControl;

    this.Controls.Add(_wpfHost);
}

此外,我创建了一个底层的ViewModel,并将其设置为WPFUI的DataContext属性,如下所示(它也是一个Singleton实现,因为我希望从多个地方访问进一步的实现-相同的实例,但此时这不是游戏中的内容):

代码语言:javascript
复制
public WPFUI()
{
    InitializeComponent();

    this.DataContext = myViewModel.GetInstance();
}

我的ViewModel属性是这样定义和使用的:

代码语言:javascript
复制
public ObservableCollection<myListViewItem> PeopleEntityResultObjects { get; private set; }

private string _NumberOfPeople;
public string NumberOfPeople
{
    get { return _NumberOfPeople; }
    set { SetField(ref _NumberOfPeople, value, () => NumberOfPeople); }
}

最后,Xaml看起来如下:

代码语言:javascript
复制
<TabControl>
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text=" People "/>
                <TextBlock Text="{Binding Path=NumberOfPeople}"/>
            </StackPanel>
        </TabItem.Header>

        <ScrollViewer x:Name="PeopleListScrollViewer">
            <ListView Name="PeopleListView" ItemsSource="{Binding Path=PeopleEntityResultObjects, Mode=OneWay}" IsSynchronizedWithCurrentItem="True">
            .
            .
            .
            </ListView>
        </ScrollViewer>
    </TabItem>
</TabControl>

为什么我的ObservableCollection<>列表更新而不是绑定属性

代码语言:javascript
复制
<TextBlock Text="{Binding Path=NumberOfPeople}"/>

?有人能猜到吗,或者我忽略了一些基本的属性定义?(在wpf应用程序中,它就是这样工作的)。

编辑

SetField()实现:

代码语言:javascript
复制
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
{
    if (selectorExpression == null)
        throw new ArgumentNullException("selectorExpression");

    MemberExpression body = selectorExpression.Body as MemberExpression;

    if (body == null)
        throw new ArgumentException("The body must be a member expression");

    OnPropertyChanged(body.Member.Name);
}

protected virtual void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;

    if (handler != null) 
        handler(this, new PropertyChangedEventArgs(propertyName));
}

protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
{
    if (EqualityComparer<T>.Default.Equals(field, value)) return false;

    field = value;

    OnPropertyChanged(selectorExpression);

    return true;
}       

你好,托马斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-21 14:27:19

使用dispatcher对象(已经用于将项插入UI绑定列表中)是成功完成此任务的关键:

代码语言:javascript
复制
if (DispatcherObject.Thread != Thread.CurrentThread)
    DispatcherObject.Invoke(new Action(() => SetField(ref _numberOfPeople, value, () => NumberOfPeople)));
else
    SetField(ref _numberOfPeople, value, () => NumberOfPeople);
票数 0
EN

Stack Overflow用户

发布于 2012-06-14 07:36:25

1)检查输出窗口中是否有绑定错误。(虽然我觉得他们还好)

2)我立即想到,PropertyChanged事件不是由您的ViewModel正确地引发的。您能显示SetField()的实现吗?我认为这是一个用于删除INotifyPropertyChanged中固有的神奇字符串的包装器

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11028307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档