我在我的智慧结束。 WPF的新手如此不确定我哪里出错了。
我有一个MS Word Interop插件,可以捕获选定的文本以及各种元数据。它组成我的模型并将数据传递给它。
对于这个开发阶段,我让我的模型成为单身,这样我就知道一切都指向同一个参考。
无论如何,我的模型由一系列条目组成。
public sealed class MYMODELSingleton : ObservableObject, IMYMODEL
{
private static MYMODELSingleton instance;
private MYMODELSingleton()
{
isActive = true;
EntryList = new List<MyEntry.IMyEntry>();
}
public static MYMODELSingleton Instance
{
get
{
if(instance == null)
{
instance = new MYMODELSingleton();
}
return instance;
}
}
public bool isActive { get; set; }
private List<MyEntry.IMyEntry> _entryList;
public List<MyEntry.IMyEntry> EntryList
{
get { return _entryList; }
set { _entryList = value; OnPropertyChanged("EntryList"); }
}
public void Add(IMYEntry mEntry)
{
try {
EntryList.Add(mEntry);
OnPropertyChanged("EntryList");
}
catch(ArgumentException ae)
{
throw ae;
}
}
ObservableObject是我制作的实现INotifyPropertyChanged
的自定义类public abstract class ObservableObject : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
#if DEBUG
MessageBox.Show("Inside Event!");
#endif
var handler = this.PropertyChanged;
if (handler != null)
{
#if DEBUG
MessageBox.Show("Event Fired!");
#endif
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion // INotifyPropertyChanged Members
}
这是我的ViewModel
public class MyEntryViewModel : ObservableObject
{
private MYMODELSingleton activeMYMODEL= MYMODELSingleton.Instance;
public MyProjectModel.MYMODEL.MYMODELSingleton ActiveMYMODEL
{
get
{
return activeMYMODEL;
}
set
{
activeMYMODEL = value;
OnPropertyChanged("ActiveMYMODEL");
}
}
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "EntryList") {
int index = activeMYMODEL.EntryList.Count - 1;
MyEntry = activeMYMODEL.EntryList[index];
UpdateGui(MyEntry.Source);
}
}
public void UpdateGui(SelectionState selState)
{
TxtDocName = selState.SelectionDocName;
TxtDocPage = selState.SelectionPage;
TxtDocText = selState.SelectionText;
}
public MyEntryViewModel()
{
this.MyEntry = new MyEntry();
activeMYMODEL.PropertyChanged += new PropertyChangedEventHandler(ModelPropertyChanged);
//This is to notify me when the VM is created
#if DEBUG
System.Windows.Forms.MessageBox.Show("ViewModelOpened!");
#endif
}
~MyEntryViewModel()
{
activeMYMODEL.PropertyChanged -= new PropertyChangedEventHandler(this.ModelPropertyChanged);
#if DEBUG
System.Windows.Forms.MessageBox.Show("ViewModel Closed!");
#endif
}
}
}
相关WPF代码
xmlns:custns="clr-namespace:MyProjectViewModel.MyEntryViewModel;assembly=MyProjectViewModel"
Title="MyProject" Height="350" Width="525" SizeToContent="Height">
<Window.Resources>
<custns:MyyEntryViewModel x:Key="MyProjectObj" />
</Window.Resources>
<Grid Name="gridEntry" DataContext="{StaticResource MyProjectObj}" >
<TextBlock x:Name="docNameTxtBx" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="20" TextWrapping="Wrap" Text="{Binding TxtDocName, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
问题是,当条目被添加到mymodel的组合List没问题时,OnPropertyChanged()中的处理程序总是等于null。尽管事实上我知道ViewModel已经实例化(由于消息框弹出)。
FWIW,Model,ViewModel,WPF和AddIn都在不同的程序集中。 Viewmodel在其构造函数中订阅了Model的事件,那么为什么我的处理程序在调用时为null?
<小时/> 更新
在与同事讨论之后,我意识到问题在于MS Word ADDIN和VM如何组成模型。两者都在不同的线程中运行,显然,两者都持有我的Singleton的单独实例!我不确定这是怎么回事。我甚至改变了我的Singleton代码,使私有实例“易变”并添加一个静态Object,然后在调用Instance.get()时锁定。
private static volatile MyModelSingleton instance;
private static object syncRoot = new Object();
private MyModelSingleton()
{
isActive = true;
EntryList = new List<MyEntry.IMyFEntry>();
}
public static MyModelSingleton Instance
{
get
{
lock (syncRoot)
{
if (instance == null)
{
instance = new MyModelSingleton();
}
}
return instance;
}
}
尽管如此,Word Interop Addin和Viewmodel都包含单独的实例。我错过了什么?
答案 0 :(得分:0)
在您提供的wpf代码中,您永远不会绑定ActiveMYMODEL
。因为它永远不会绑定在你的xaml中,所以你永远不会挂钩通知你创建的属性更改事件。