2014-10-20 28 views
0

[编辑]例reprodoucing这个问题Host to AddIn issue我的视图模型不提供当前变量值

我想写一个主机应用程序是可扩展的,并且使用几个接口。其中之一是

public MessageCreator GetMessageCreator() 
{ 
var creator = new AVL2MessageCratorFactory(); 
return creator.Create(new AVL2DataForMessageCreatingImpl { Imei = VM.Imei }); 
} 

从外接程序和下面你可以找到外接程序客户应用的XAML:从视图模型

using System.ComponentModel; 

namespace AVL2SimulatorAddView 
{ 
public class AVL2ViewModel : INotifyPropertyChanged 
{ 
    readonly AVL2Model _avl2Model = new AVL2Model(); 

    public string Imei 
    { 
     get { return _avl2Model.Imei; } 
     set 
     { 
      if (value == _avl2Model.Imei) return; 
      _avl2Model.Imei = value; 
      OnPropertyChanged("Imei"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
    } 
} 

在调试模式

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:AVL2SimulatorAddView="clr-namespace:AVL2SimulatorAddView" x:Class="AVL2SimulatorAddView.AVL2AddInUI"> 

<Grid Height="46" Width="344"> 
    <Grid.DataContext> 
     <AVL2SimulatorAddView:AVL2ViewModel x:Name="VM" /> 
    </Grid.DataContext> 
    <Label Content="Starting IMEI" Margin="0,0,255,0" Height="29" VerticalAlignment="Top" /> 
    <TextBox Text="{Binding Path=Imei, UpdateSourceTrigger=PropertyChanged }" Margin="120,2,48,0" Width="176" Height="27" VerticalAlignment="Top" /> 
</Grid> 

维明财产我看到ViewModel中的属性更新每个字符都写在TextBox中,但是当GetMessag时eCreator()从主机应用程序被称为它看起来像新的空虚拟机和它的Imei返回(我没有看到主机应用端Imei)

我错过了一些保护.NET中反对绕过绑定数据?其他“硬编码”字符串传递良好。主机应用程序端的MVVM和DataContext也可以正常工作。我尝试了不同类型的UpdateSourceTrigger,但它似乎总是在AddIn方面工作,并且它不提供共享接口的当前日期。

[编辑] 其它控制绑定到IMEI,显示上线的变化,当数据在文本框中输入

调用本地按钮适当地设定标签内容从

private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    label1.Content = VM.Imei; 
} 

临时呼叫方法主机应用程序

var msgCreator = _tabsMap[(TabItem) tabControl1.SelectedItem].GetMessageCreator(); 
+0

你描述的不是WPF的“行为”,其实这个问题很奇怪。很难说出是怎么回事,我建议你把简单的测试项目放在一起来证明这一点。粘贴你的整个视图模型。 – 2014-10-20 15:31:18

+0

一般来说,在我的粘贴代码中,这几乎是整个ViewModel - 只有INotifyPropertyChanged成员,并且缺少_avl2Model(包含一个字符串属性的类)声明。 很难准备示例,因为我认为这与.NET中的AddIn相关 - 我的项目中的所有MVVM都能正常工作。即使访问此AddIn中的虚拟机也可以将其绑定到其他控件并不断更新,或者可以通过简单的分配直接请求标签内容。 – 2014-10-20 15:53:14

+0

谁在调用'GetMessageCreator'方法? – 2014-10-20 16:39:33

回答

1

我指的是您的演示项目。在LoadGeneratorWPFHostApplication.MainWindow构造考虑以下代码:

// Activate creates instance AAddIn#1 (wpfAddInHostView.wpfAddInContract.wpfAddInView) 
foreach (var wpfAddInHostView in addInTokens.Select(addInToken => addInToken.Activate<IWpfAddInHostView>(AddInSecurityLevel.Host))) 
{ 
    // AAddin#1.GetAddinUI creates instance AAddIn#2 (tabItem.Content) 
    var tabItem = new TabItem {Content = wpfAddInHostView.GetAddInUI(), Header = wpfAddInHostView.GetName()}; 
    tabControl1.Items.Add(tabItem); 
    // adding AAddIn#1 to _tabsMap (but using AAddIn#2 on the UI). 
    _tabsMap.Add(tabItem, wpfAddInHostView); 
} 

所以这里发生的事情是,你使用System.AddIn.Hosting.AddInToken.Activate创建的AAddIn(#1)的实例。但在此之后,您使用此AAddIn#1以其方法GetAddInUI创建另一个实例。

public partial class AAddIn : WPFAddInView 
{ 
    public FrameworkElement GetAddInUI() 
    { 
     return new AAddIn(); // creates a new instance of itself 
    } 
} 

AAddIn#1持续合同(WPFAddIn_ContractToViewHostSideAdapter.wpfAddInContract.wpfAddInView)上,并在_tabsMap,AAddIn#2在UI(tabItem.Content)被使用。

有不同的方式,以确保你保持相同的情况下,我可能只是删除从WPFAddInView接口(注:always start interface names with an I)的GetAddInUI方法还有AAddIn类,然后直接返回wpfAddInView的合同:

public class WPFAddIn_ViewToContractAddInSideAdapter : ContractBase, IWPFAddInContract 
{ 
    public INativeHandleContract GetAddInUI() 
    { 
     FrameworkElement fe = this.wpfAddInView as FrameworkElement; // return instance directly instead of creating new one by wpfAddInView.GetAddInUI(); 
     INativeHandleContract inhc = FrameworkElementAdapters.ViewToContractAdapter(fe); 
     return inhc; 
    } 
} 

备注:在调试器中使用方法.GetHashCode()来区分同一类的实例。

enter image description here

+0

是的,就是这样!我认为这可能是两个不同的例子,但我不知道它可以放在哪里。 “我”还介绍了信。 也许你知道一些方法来避免将来这样的问题?这对我来说是新的东东<->合同<->插件解决方案。 – 2014-10-24 11:06:22

+1

对我来说,你的问题与托管插件框架模式没有直接关系,只是模式具有固有的复杂性。我可以提供的唯一建议就是尽量减少主机和插件之间的交互。无论你在插件中直接处理什么,都可以在那里做到。至于问题本身,你已经猜到了不同的实例有问题,从那里你应该真的只是调试(可能使用前面提到的'GetHashCode'方法),试图找出哪个类负责(创建)不同的实例。 – 2014-10-24 11:36:26

相关问题