2014-10-20 24 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

相關問題