C# 从xml文件反序列化数据后绑定到静态字段-Windows应用商店应用

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

我使用“INotifyPropertyChanged”将数据从XML文件中获取到一个名为ExerciseTable的类中。我想将数据绑定到静态文本块,而不使用任何ListView或GridView项资源。

这是我的班级:

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。请允许我告诉你四种方法

  • 在XAML中实例化它
  • 使用此代码:

    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