2015-10-02 78 views
0

我使用Wpf 4.5和Caliburn Micro 2.0.2。Wpf + Caliburn Micro:將文本框綁定到自定義對象

我想將文本框綁定到視圖模型的屬性。該屬性(稱爲ResultData)是類TextXmlData中的一個對象。該類是從xsd自動生成的類。我使用Microsoft Xsd.exe來製作它。

這是視圖模型

public class ShellViewModel : PropertyChangedBase, IHaveDisplayName 
{ 
    public string DisplayName { get; set; } 
    private TestXmlData _resultData; 
    public TestXmlData ResultData 
    { 
     get { return _resultData; } 
     set 
     { 
      _resultData = value; 
      NotifyOfPropertyChange(() => _resultData); 
     } 
    } 

    public ShellViewModel() 
    { 
     DisplayName = "Shell Window"; 
    } 

    public void CreateObject() 
    { 
     String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>"; 
     if (ResultData == null) { ResultData = new TestXmlData(); } 
     XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType()); 
     ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData)); 
     // at this point the debugger shows that the ResultData is correctly filled, 
     // the Name is definitely not empty 
    } 
} 

,這是視圖

<UserControl x:Class="CMWpfXmlSerializer2Ways.Views.ShellView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     d:DesignHeight="300" 
     d:DesignWidth="300" 
     mc:Ignorable="d"> 
<Grid Width="300" Height="300"> 
    <StackPanel Width="200" 
       Height="100" 
       HorizontalAlignment="Center" 
       VerticalAlignment="Center"> 
     <Button x:Name="CreateObject" 
       Width="190" 
       Content="Create Object from XML" /> 
     <TextBox Width="190" 
       DataContext="{Binding ResultData}" 
       Text="{Binding Name}" /> 
    </StackPanel> 

</Grid> 
</UserControl> 

和文本框顯示總是空的!

我也嘗試過使用Text =「{Binding ResultData.Name}」,但TextBox仍然顯示爲空。

任何人都可以幫助並告訴我上面的代碼有什麼問題嗎? 請隨時修改代碼。 在此先感謝。

+0

是你的'ResultData'爲空/空嗎? –

+0

TestXmlData中的屬性 – mvermef

+0

@AbinMathew我ViewModel中的ResultData具有正確的內容,所以它不是空的,也不爲空。 – MagB

回答

1

ResultData是ViewModel的一個屬性。因此,您需要將ViewModel設置爲更高級別的DataContext,然後您可以將其屬性用作較低級別的綁定源。

要運行您的樣品,我做了一些改變,跑象下面這樣:

<TextBox x:Name="tbName" DataContext="{Binding ResultData}" Text="{Binding Name}" /> 

///

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     ShellViewModel vm = new ShellViewModel(); 
     vm.CreateObject(); 

     this.DataContext = vm; 
    } 
    ... 

///

public class ShellViewModel : INotifyPropertyChanged 
    { 
     public string DisplayName { get; set; } 
     private TestXmlData _resultData; 
     public TestXmlData ResultData 
     { 
      get { return _resultData; } 
      set 
      { 
       _resultData = value; 
       OnPropertyChanged("ResultData"); 
      } 
     } 

     public void OnPropertyChanged(string name) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 

     public ShellViewModel() 
     { 
      DisplayName = "Shell Window"; 
     } 

     public void CreateObject() 
     { 
      String xmlData = "<TestXmlData><Id>88</Id><Name>What a name</Name></TestXmlData>"; 
      if (ResultData == null) { ResultData = new TestXmlData(); } 
      XmlSerializer oXmlSerializer = new XmlSerializer(ResultData.GetType()); 
      ResultData = (TestXmlData)oXmlSerializer.Deserialize(new StringReader(xmlData)); 
      // at this point the debugger shows that the ResultData is correctly filled, 
      // the Name is definitely not empty 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
+0

您的視圖和我的視圖命令(xaml)幾乎沒有區別,除了x:Name,在我的情況下可以忽略。你的建議使用普通的WPF,但我使用Caliburn Micro Framework,所以我不需要明確地聲明PropertyChanged等。我感謝你的努力來幫助。 – MagB

+0

你讀過我的回答嗎?將DataContext根目錄設置爲ShellViewModel,或將TextBox的DataContext更改爲DataContext =「{Binding myShellViewModel.ResultData}」,其中myShellViewModel是VM實例。 – AnjumSKhan

+0

當然,我已閱讀你的答案。更改我的TextBox的DataContext和我得到:System.Windows.Data錯誤:40:BindingExpression路徑錯誤:'''''''''''''''''('HashCode = 32957278)''上找不到'ShellViewModel'屬性。我不需要更改根的DataContext,因爲Caliburn Micro Framework與命名約定一起工作,因此框架會自動綁定ShellView.xaml和ShellViewModel.cs – MagB

1

你已經啓用調試與Caliburn.MIcro?這將從您的BootStrapper完成。這將告訴我們您的視圖和視圖模型是否被正確綁定。

通常放置在引導程序的CTOR中 LogManager.GetLog = type => new DebugLog(type);

由於您正在爲您的shellview使用UserControl,我希望看到您的BootStrapper。

我懷疑有些東西不正確或名稱空間設置不正確,這會導致綁定錯誤。

+0

引導程序是好的,因爲如果我將TextBox綁定到具有值爲String的屬性(public String SomeProperty),它就可以工作。 – MagB

0

我一遍又一遍地閱讀您的意見,提示,建議和我的代碼後,偶然發現問題的原因。它是我自己的錯(是的,我的愚蠢的錯誤)

我已經使用上NotifyOfPropertyChange 支持字段_resultData,而不是屬性名ResultData! (請在視圖模型中查看屬性ResultData的設置程序)

非常感謝大家!

+0

使用'[CallerMemberName]'屬性而不是成員表達式可以防止這種錯誤。如果在Visual Studio中沒有一個,您還可以爲更改通知屬性創建代碼片段。編輯:爲了澄清,你的'NotifyOfPropertyChange'方法的簽名將是'NotifyOfPropertyChange([CallerMemberName] string propertyName = null)',你只需要在你的屬性的setter中不帶參數地調用它。編譯器將爲您插入屬性名稱作爲字符串。 –

+0

2.02應該已經有了... NotifyPropertyChange()應該與lambda – mvermef

相關問題