我构建了一个 Office 2010 Word 插件,向其中添加了一个 Windows 窗体元素,并在包含我的 WPF 的 ElementHost 对象中添加了一个。
这就是问题所在:我遇到了问题,在 Xaml 代码中定义并在 ViewModel 实现中设置的公共属性(DP)没有更新(参见下面的代码),即使我在调试时找不到任何错误代码。这仅适用于我得到的属性,此外,我得到了一些 ObservableCollection<> 列表,它们的更新没有任何问题。有人有想法吗?我认为我可以在代码中自己定义属性,如下所示:
public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource",typeof(string),typeof(usercontrol1));
但这也不起作用(例如,我刚刚将此行添加到 Xaml 文件的代码隐藏文件中 - 并留下了其他任何内容)
我的代码看起来是这样的:
Forms 元素的构造函数(它实际上是私有的,因为我将它实现为 Singleton):
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 属性,就像这样(它也是一个单例实现,因为我想在进一步的实现中从多个地方访问同一个实例,但此时这不会进入游戏):
public WPFUI()
{
InitializeComponent();
this.DataContext = myViewModel.GetInstance();
}
我的 ViewModel 属性是这样定义和使用的:
public ObservableCollection<myListViewItem> PeopleEntityResultObjects { get; private set; }
private string _NumberOfPeople;
public string NumberOfPeople
{
get { return _NumberOfPeople; }
set { SetField(ref _NumberOfPeople, value, () => NumberOfPeople); }
}
最后 Xaml 看起来像这样:
<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<> 列表更新但没有绑定属性
<TextBlock Text="{Binding Path=NumberOfPeople}"/>
? 谁能猜到,或者我错过了一些基本的属性定义?(在 wpf 应用程序中它以这种方式工作)。
编辑
SetField() 实现:
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;
}
问候,托马斯