2013-03-10 51 views
1

好吧,我们现在正在为我们的GUI尝试使用XAML(以及我们正在学习)......我已经能够在XAML和C#中独立于一个数据绑定另一个,但现在是时候我需要来回传递值,我有点失落。当我编译并尝试导航到页面时,它将引发XamlParseException:指定的类名称与实际的根实例类型不匹配。删除Class指令或通过XamlObjectWriterSettings.RootObjectInstance提供实例。 5号线位置2将XAML加载到C#进行数据绑定

任何帮助或在正确的方向轻柔推是极大的赞赏:)

这里就是我:

namespace TheAirline.GraphicsModel.PageModel.PageFinancesModel 
{ 
    /// <summary> 
    /// Interaction logic for PageFinances.xaml 
    /// </summary> 
    public partial class PageFinances : Page 
    { 
     private Airline Airline; 

     public PageFinances(Airline airline) 
     { 
      InitializeComponent(); 
      this.Language = XmlLanguage.GetLanguage(new CultureInfo(AppSettings.GetInstance().getLanguage().CultureInfo, true).IetfLanguageTag); 

      this.Airline = airline; 
      Page page = null; 
//loading the XAML 
      using (FileStream fs = new FileStream("TheAirline\\GraphicsModel\\PageModel \\PageFinancesModel\\PageFinances.xaml", FileMode.Open, FileAccess.Read)) 
      { 
      page = (Page)XamlReader.Load(fs); 
      } 
//finding XAML element and trying to set the value to a variable 
      string airlineCash = GameObject.GetInstance().HumanAirline.Money.ToString(); 
      TextBox cashValue = (TextBox)page.FindName("cashValue"); 
      cashValue.DataContext = airlineCash; 
     } 
    } 
} 

而XAML的前几行:

<Page 
    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" 
    xmlns:AirlineModel="clr-namespace:TheAirline.Model.AirlineModel" 
    mc:Ignorable="d" 
x:Class="TheAirline.GraphicsModel.PageModel.PageFinancesModel.PageFinances" 
    xmlns:c="clr-namespace:TheAirline.GraphicsModel.Converters" 
...> 
</Page> 
+0

你的发言'我已经能够做到数据,而无需在XAML和C#彼此独立,的问题结合,但现在来了,我需要通过值来回的时间,我有点lost'完全矛盾。如果你使用'DataBind','DataBinding' ITSELF'来回传递数据。我不明白你的意思。此外,你不应该做的事情,比如'文本框cashValue =(文本框)page.FindName( “cashValue”);'和'cashValue.DataContext = airlineCash;'。请说明你需要什么,我们可以帮助你。 – 2013-03-10 09:14:03

+0

对不起,如果这是有点模糊(和矛盾) - 仍然学习XAML的来龙去脉。 无论如何 - 我的意思是我能够将滑块的值绑定到XAML或c#中的文本框,但无法将在XAML中创建的值绑定到c#中的变量,反之亦然。我希望这更有意义:) – mikedugan 2013-03-10 10:08:39

回答

1

在XAML Bindings是针对被分配给任何给定的XAML元件的DataContext属性的对象解决。该属性的值(以及许多其他属性)Is Inherited在任何给定的Visual Tree中从父元素到子元素。

例如,考虑这个类:

public namespace MyNamespace 
{ 
    public class ViewModel 
    { 
     public string Name {get;set;} 
     public bool IsActive {get;set;} 
    } 
} 

这XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:MyNamespace" 
     FontSize="20"> 
    <Window.DataContext> 
     <local:ViewModel> 
    </Window.DataContext> 
    <StackPanel> 
     <TextBox Text="{Binding Path=Name}"/> 
     <CheckBox IsChecked="{Binding Path=IsActive}"/> 
    <StackPanel> 
</Window> 

XAML中定义的所有四个对象,在Window,将StackPanel,在TextBoxCheckBox,将FontSize为20,ViewModel类的实例分配为DataContext属性。因此,所有绑定(不包括与指定的ElementName,RelativeSourceSource的绑定)将针对该实例进行解析。

如果属性代码,而不是在XAML分配这将是完全一样的:

public MyWindow() //Window Constructor 
{ 
    InitializeComponent(); 
    this.DataContext = new ViewModel(); //Note that keyword "this" is redundant, I just explicity put it there for clarity. 
} 

因此,没有必要设置DataContext属性为每个元素明确,作为框架已经在考虑这一点。

另外,请注意,在XAML中,大多数内置的Markup Extensions都有一个默认的构造函数约定,可以让您缩减它们的用法。在Binding Markup Extension的情况下,默认的构造函数有Path属性,因此这样的:

<TextBox Text="{Binding Path=Name}"/> 

是完全一样的:现在

<TextBox Text="{Binding Name}"/> 

,在底层的DataContext属性更改为自动从绑定源(ViewModel)传递到绑定目标(XAML定义的对象),源对象必须实现System.ComponentModel.INotifyPropertyChanged接口并在每次属性更改时引发PropertyChanged事件。

因此,为了支持双向绑定,例如类应该是这样的:

public namespace MyNamespace 
{ 
    public class ViewModel: INotifyPropertyChanged 
    { 
     private string _name; 
     public string Name 
     { 
      get 
      { 
       return _name; 
      } 
      set 
      { 
       _name = value; 
       NotifyPropertyChanged("Name"); 
      } 
     } 

     private bool _isActive; 
     public bool IsActive 
     { 
      get 
      { 
       return _isActive; 
      } 
      set 
      { 
       _isActive = value; 
       NotifyPropertyChanged("IsActive"); 
      } 
     } 
    } 

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

注意,ViewModel类没有依赖或直接引用任何XAML定义对象,但它仍然包含将出现在UI中的属性的值。这允许在UI和应用程序逻辑/数据(称为MVVM Pattern)之间完全解耦。我强烈建议你在该课题的研究,如果你希望成功,在C#+ XAML程序,因为它是一个激进的思维转变相比其他传统的UI范例。

例如,不建议在基于XAML的应用程序是这样的:

if (myWindow.CheckBox1.IsChecked) 
    //Do Something 

,因为这将意味着你耦合应用逻辑并使其依赖于UI元素,的状态,这正是你需要避免的。

请注意,所有的链接,并在这个答案中引用的所有概念属于WPF,但也适用于Silverlight和WinRT的。由于您没有指定您使用的三个基于XAML的框架中的哪一个,我发布了WPF框架,这是我最熟悉的框架。

+0

感谢您的答案。我发现我在本地的问题很简单,但你的回答提供了很多我没有的背景信息:) – mikedugan 2013-03-16 14:41:02