使用Blend。
我正在尝试将GridView或TextBlock绑定到Observable集合。可观察集合从XML文件中获取其数据。我的测试程序运行,但当我按下“显示句子”按钮时,GridView或TextBlock中没有数据显示。
我的XML文件:
(从一个在Visual Studio控制台项目中正常运行的大型复杂文件中模拟)
<Book ISBN ="9144252184178">
<Title>
<TitleLine>Title First Line</TitleLine>
<TitleLine>Title Second Line</TitleLine>
</Title>
<Authors>
<Author>Some Body</Author>
<Author>No Body</Author>
</Authors>
<Pages>
<Page PageNumber ="1">
<Sentences>
<Sentence SentenceID = "1">
<SentenceText>Once there was a giant </SentenceText>
<SentenceFileName>9144252184178.1.1</SentenceFileName>
<SentenceWords>
<SentenceWord Start = "" Part = "">once</SentenceWord>
<SentenceWord Start = "" Part = "">there</SentenceWord>
<SentenceWord Start = "" Part = "">was</SentenceWord>
<SentenceWord Start = "" Part = "">a</SentenceWord>
<SentenceWord Start = "" Part = "">giant</SentenceWord>
</SentenceWords>
</Sentence>
<Sentence SentenceID = "2">
<SentenceText>Every day, etc</SentenceText>
<SentenceFileName>9144252184178.1.2</SentenceFileName>
<SentenceWords>
<SentenceWord Start = "" Part = "">every</SentenceWord>
<SentenceWord Start = "" Part = "">day</SentenceWord>
<SentenceWord Start = "" Part = "">etc</SentenceWord>
</SentenceWords>
</Sentence>
</Sentences>
</Page>
</Pages>
</Book>
MainPage.xaml中:
(显示我试图绑定到ObservableCollection失败的几种方法)
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Button x:Name="button" Content="Show Sentence" Click="button_Click"/>
<GridView Background="Bisque" ItemsSource="{x:Bind ThisSentence}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Sentences">
<StackPanel Background="AliceBlue">
<TextBlock Text="Sentence"/>
<TextBlock Text="{x:Bind SentenceID}"/>
<TextBlock Text="{x:Bind SentenceText}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border Background="LightBlue">
<TextBlock Text="{Binding ThisSentence.SentenceID, Mode=OneWay}"/>
</Border>
</StackPanel>
</Grid>
MainPage.xaml.cs中:
namespace ImportFromXML
{
public sealed partial class MainPage : Page
{
private ObservableCollection<Book> thisSentence_;
public ObservableCollection<Book> ThisSentence
{
get { return thisSentence_; }
set { thisSentence_ = value; }
}
public MainPage()
{
this.InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
var newTask = Task.Run(() => thisSentence_ = SentenceManager.GetSentence("0","0")) ;
DataContext = ThisSentence;
}
}
}
Book.cs:
(这是我的类和我的SentenceManager。在VS Console项目中运行时,SentenceManager Linq代码对我的XML起作用。)
public class Book
{
public string ISBN { get; set; }
public IList<Title> title = new List<Title>();
public IList<Authors> authors = new List<Authors>();
public IList<Pages> pages = new List<Pages>();
}
public class Title
{
public string TitleLine { get; set; }
}
public class Authors
{
public string AuthorName { get; set; }
}
public class Pages
{
public string PageNumber { get; set; }
public IList<Sentences> sentences = new List<Sentences>();
public IList<Contents> contents = new List<Contents>();
}
public class Sentences
{
public string SentenceID { get; set; }
public string SentenceText { get; set; }
public string SentenceFileName { get; set; }
public IList<SentenceWords> sentenceWords = new List SentenceWords>();
}
public class SentenceWords
{
public string SentenceWord { get; set; }
public string Ending { get; set; }
public string Parent { get; set; }
}
public class SentenceManager
{
public static ObservableCollection<Book> GetSentence(string pageNumber, string sentenceID)
{
XDocument xdoc = XDocument.Load(@"C:\Users\Richard\Documents\ImportFromXML\book.xml");
List<Book> sentence = (from bk in xdoc.Elements("Book")
select new Book
{
pages = (from pag in bk.Element("Pages").Elements("Page")
where (string)pag.Attribute("PageNumber") == pageNumber
select new Pages
{
sentences = (from sen in pag.Element("Sentences").Elements("Sentence")
where (string)sen.Attribute("SentenceID") == sentenceID
select new Sentences
{
SentenceID = sen.Attribute("SentenceID").Value,
SentenceText = sen.Element("SentenceText").Value,
SentenceFileName = sen.Element("SentenceFileName").Value,
}).ToList(),
}).ToList(),
}).ToList();
ObservableCollection <Book> Sentence = new ObservableCollection<Book>(sentence);
return Sentence;
}
}
在我的程序中,我必须将许多控件绑定到我的xml数据的各个部分,所以这只是一个例子。
我是一个新手,所以请不要让你的建议太神秘,否则我可能不理解!感谢你给与我的帮助。
答案 0 :(得分:0)
首先,当您通过ThisSentence
绑定x:Bind
属性时
ItemsSource="{x:Bind ThisSentence}"
根本没有必要设置DataContext
。
但是,绑定模式必须设置为OneWay
,因为默认值为OneTime
:
ItemsSource="{x:Bind ThisSentence, Mode=OneWay}"
此外,酒店必须通知价值变化。在从DependencyObject派生的类中,通常通过使其成为依赖属性来完成:
public static readonly DependencyProperty ThisSentenceProperty =
DependencyProperty.Register(
"ThisSentence",
typeof(MainPage),
typeof(ObservableCollection<Book>),
new PropertyMetadata(null));
public ObservableCollection<Book> ThisSentence
{
get { return (ObservableCollection<Book>)GetValue(ThisSentenceProperty); }
set { SetValue(ThisSentenceProperty, value); }
}
您还应该等待Click处理程序中的Task。
private async void button_Click(object sender, RoutedEventArgs e)
{
ThisSentence = await Task.Run(() => SentenceManager.GetSentence("0", "0"));
}
请注意,事件处理程序是规则的例外,不应该是任何async void
方法。
如果您想使用Binding
而不是x:Bind
,您应该在Page的构造函数中设置一次DataContext,例如
public MainPage()
{
InitializeComponent();
DataContext = this;
}
现在你也可以写
ItemsSource="{Binding ThisSentence}"