C# 从xml文件反序列化数据后绑定到静态字段-Windows应用商店应用
我使用“INotifyPropertyChanged”将数据从XML文件中获取到一个名为ExerciseTable的类中。我想将数据绑定到静态文本块,而不使用任何ListView或GridView项资源。 这是我的班级:C# 从xml文件反序列化数据后绑定到静态字段-Windows应用商店应用,c#,xml,binding,windows-store-apps,winrt-xaml,C#,Xml,Binding,Windows Store Apps,Winrt Xaml,我使用“INotifyPropertyChanged”将数据从XML文件中获取到一个名为ExerciseTable的类中。我想将数据绑定到静态文本块,而不使用任何ListView或GridView项资源。 这是我的班级: public class ExerciseTable : INotifyPropertyChanged { int questionsNum; bool feedback; bool randomAnswers; public int Ques
public class ExerciseTable : INotifyPropertyChanged
{
int questionsNum;
bool feedback;
bool randomAnswers;
public int QuestionsNum
{
get { return questionsNum; }
set
{
questionsNum = value;
RaisePropertyChanged("QuestionsNum");
}
}
public bool Feedback
{
get { return feedback; }
set
{
feedback = value;
RaisePropertyChanged("Feedback");
}
}
public bool RandomAnswers
{
get { return randomAnswers; }
set
{
randomAnswers = value;
RaisePropertyChanged("RandomAnswers");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
以下是我反序列化XML文件的方式:
string XMLPathEx = System.IO.Path.Combine(Package.Current.InstalledLocation.Path, "Assets/TableOfExercises.xml");
XDocument loadedEx = XDocument.Load(XMLPathEx);
//retrieving data from xml using LINQ
var exercise = from query in loadedEx.Descendants("exercise")
select new ExerciseTable
{
QuestionsNum = int.Parse(query.Element("settings").Attribute("qNum").Value),
Feedback = System.Convert.ToBoolean(query.Element("settings").Attribute("feedback").Value),
RandomAnswers = System.Convert.ToBoolean(query.Element("settings").Attribute("randomAnswers").Value)
};
这就是我绑定到文本块的方式:
<TextBlock x:Name="NumberQuestion" Text="{Binding ExerciseTable.QuestionsNum}"/>
真正的问题是如何设置textblock的数据上下文。您说“不使用任何listview”的原因向我清楚地表明,您不能100%确定在没有像listview这样的repeater控件的情况下如何设置datacontext。请允许我告诉你四种方法
public class Locator {
public ExcersizeTable CurrentTable {
get {
return new ExcersizeTable();
}
}
}
public class MainPage: Page {
public MainPage() {
Loaded += MainPage_Loaded;
}
public void MainPage_Loaded() {
MyTextBlock.DataContext = new ExcercizeTable();
}
}
public class MainPage: Page {
public MainPage() {
Loaded += MainPage_Loaded;
}
public void MainPage_Loaded() {
MyTextBlock.Text = new ExcercizeTable().Text;
}
}
没有
使用此XAML:
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<models:ExerciseTable />
</TextBlock.DataContext>
</TextBlock>
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<Binding Path="CurrentTable">
<Binding.Source>
<models:Locator />
</Binding.Source>
</Binding>
</TextBlock.DataContext>
</TextBlock>
<TextBlock x:Name="MyTextBlock" Text="{Binding QuestionsNum}" />
<TextBlock x:Name="MyTextBlock" />
使用此XAML:
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<models:ExerciseTable />
</TextBlock.DataContext>
</TextBlock>
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<Binding Path="CurrentTable">
<Binding.Source>
<models:Locator />
</Binding.Source>
</Binding>
</TextBlock.DataContext>
</TextBlock>
<TextBlock x:Name="MyTextBlock" Text="{Binding QuestionsNum}" />
<TextBlock x:Name="MyTextBlock" />
使用此XAML:
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<models:ExerciseTable />
</TextBlock.DataContext>
</TextBlock>
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<Binding Path="CurrentTable">
<Binding.Source>
<models:Locator />
</Binding.Source>
</Binding>
</TextBlock.DataContext>
</TextBlock>
<TextBlock x:Name="MyTextBlock" Text="{Binding QuestionsNum}" />
<TextBlock x:Name="MyTextBlock" />
使用此XAML:
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<models:ExerciseTable />
</TextBlock.DataContext>
</TextBlock>
<TextBlock Text="{Binding QuestionsNum}">
<TextBlock.DataContext>
<Binding Path="CurrentTable">
<Binding.Source>
<models:Locator />
</Binding.Source>
</Binding>
</TextBlock.DataContext>
</TextBlock>
<TextBlock x:Name="MyTextBlock" Text="{Binding QuestionsNum}" />
<TextBlock x:Name="MyTextBlock" />
每种方法都是正确的方法,具体取决于项目的细节。大多数开发人员使用#4是因为他们不了解数据绑定。通常,我使用更高级别的datacontext,如下所示:
<Grid>
<TextBlock.DataContext>
<Binding Path="CurrentTable">
<Binding.Source>
<models:Locator />
</Binding.Source>
</Binding>
</TextBlock.DataContext>
<TextBlock Text="{Binding QuestionsNum}" />
<TextBlock>
<Run Text="Feedback:" />
<Run Text="{Binding Feedback}" />
</TextBlock>
</Grid>
请注意,这种方法允许您在只设置一次datacontext时绑定到两个属性。这是因为datacontext是XAML中一种特殊类型的属性,称为依赖属性。这个特定依赖属性的一个简洁特性是,它的值通过XAML树向下流到每个未显式设置自己的datacontext的子元素
这允许您在XAML树中将元素的datacontext属性设置得非常高,并在子元素中重用它,而无需重新声明它
像listview这样的XAML转发器是如何做到的?完全一样,就在被子下面。当它为列表中的每个记录重复自身时,它将创建一个新的子XAML树,并将datacontext设置为当前正在处理的单个元素。然后您的数据绑定工作
自行设置datacontext是在XAML中构建接口的好方法。也就是说,我的所有示例都将datacontext设置为模型。这是可行的,但通常不是建议的方法。大多数开发人员将他们的模型包装在一个包含类中,我们称之为视图模型。视图模型是大多数开发人员设置datacontext值的对象
这不是教MVVM的合适地方,但我认为你应该研究一下。效果很好,有很多博客和视频教MVVM。这是一种非常简单的设计模式,非常适合XAML应用程序
我希望这能回答你的问题
祝你好运 你的问题我不清楚。是否要同时将textblock绑定到QuestionsUM、Feedback和RandomAnswers属性?然后一起展示?不只是问题。绑定不起作用,没有显示任何内容…您是否为textblock或其任何父项(包括Windows)设置了datacontext?否,如何设置?编写
NumberQuestion.datacontext=exercise代码>在反序列化之后立即执行;并将绑定更改为QuestionsNum
而不是ExerciseTable.QuestionsNum