2016-11-30 11 views
0

ブレンドの使用。XMLから取り込まれたObservableCollectionへのバインドが機能しない

GridViewまたはTextBlockをObservableコレクションにバインドしようとしています。観測可能なコレクションは、そのデータをXMLファイルから取得します。私のテストプログラムは動作しますが、[Show Sentence]ボタンを押すとG​​ridViewまたはTextBlockにデータが表示されません。

私のXMLファイル:

(Simlpified Visual StudioのコンソールプロジェクトでOK働く大規模かつ複雑なファイルから)

<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です。 SentenceManager LINQのコード私のプログラムでVSコンソールプロジェクトで実行したときに、私の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

まず、あなたが

ItemsSource="{x:Bind ThisSentence}" 

ようx:BindによってThisSentenceプロパティにバインドするとき、すべてでDataContextを設定する必要はありません。デフォルトはOneTimeあるため

しかし、結合モードは、OneWayに設定されなければならない。また

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); } 
} 

はまた、クリックハンドラ内でタスクを待つ必要があります。

private async void button_Click(object sender, RoutedEventArgs e) 
{ 
    ThisSentence = await Task.Run(() => SentenceManager.GetSentence("0", "0")); 
} 

イベントハンドラは、任意のasync void方法があってはならないという規則の例外であることに注意してください。あなたがBinding代わりのx:Bindを使用したい場合には


、あなたは

public MainPage() 
{ 
    InitializeComponent(); 
    DataContext = this; 
} 

のように今、あなたはまた、私が持っている

ItemsSource="{Binding ThisSentence}" 
+0

を書くことができ、ページのコンストラクタで一度のDataContextを設定する必要があります両方の提案を実装しましたが、GridViewまたはTextBlockのいずれにも何も表示されません。 – RichPro

+0

DataContextを設定する必要はありませんでした。編集された答えを参照してください。 – Clemens

+0

typeof(MainWindow)でエラーが発生します。型または名前空間の名前 'MainWindowが見つかりませんでした。 – RichPro

関連する問題