2010-08-02 46 views
1

我正在嘗試編寫解碼一些無符號長整型值的應用程序。每個值的格式用XML表示爲:WPF中的XML數據綁定

<Project Name="Project1"> 
<Message Name="a"> 
    <BitField high="31" low="28"> 
    <value>0001</value> 
    <value>1010</value> 
    </Bitfield> 
    <BitField high="27" low="17"> 
    <value>000111101</value> 
    </BitField> 
    <BitField high="16" low="0">100h</BitField> 
</Message> 
</Project> 

現在項目值出現在組合框中。當用戶在組合框中選擇一個值時,消息類型必須顯示在列表框中。然後,當用戶在列表框中選擇消息類型時,必須顯示它們可以容納的位域和值。現在,當用戶爲每個位域選擇一個值時,最終的雙字值必須顯示在文本框中。

我遇到了一些例子來解析一個完整的XML,但不涉及到選擇。需要你們在這裏幫忙。

還有一件事是用戶可以在文本框中輸入雙字值。現在我怎麼做這個反向綁定的解碼在文本框中的DWORD,並顯示相應的消息+值使用上面解釋的UI?

UPDATE:現在我已經完成了顯示項目值的組合框和顯示消息的列表框之間的綁定。接下來我要做的是,當用戶在列表框中選擇一條消息時,位域必須顯示爲具有「高」,「低」,「值/ @名稱」(此處未顯示)的行,然後值(綁定到值/ @名稱)作爲列。值/ @名稱必須顯示爲組合框。我敢肯定,我可以在dataGrid中做到這一點,但我使用.net 3.5,所以在這裏尋找替代品。此外,值文本塊必須是可編輯的,以便<值>節點不存在於xml中。最後,我要將「值」列中的條目打包爲DWORD。我可以在沒有數據網格的情況下在XAML中執行此操作嗎?什麼是.Net 3.5的數據網格的替代?

+0

什麼是C#WPF?這與VB.NET WPF有什麼不同? – 2010-08-05 05:32:46

+0

致約翰:WPF與公共語言運行時(CLR)代碼集成。 AFAIK這可以從任何.NET語言生成,但肯定是由C#.NET和VB.NET生成的,所以基本上不管使用什麼語言,都可以使用相同的功能。 – 2010-08-08 15:48:18

回答

2

這裏有兩個不同的問題 - XML解析問題和轉換問題。

對於綁定工作,您需要將XML解析爲表示其值的類。對於轉換問題,我將您指向TypeConverters的概念,這些概念非常簡單易用。對於XML解析問題,我想強調LINQ-to-XML,我認爲這是蜜蜂跪下的問題。它的幾行可以重構來自XML源的最複雜的對象圖。對於Project/Message/BitField的例子,我已經部分實現了一個解決方案,可以給你這個模式。

請注意「LoadFromXml」方法。這使用填充對象圖的linq-to-xml表達式。有一件事是,在你的XML源此查詢的變化是,它期待着收集節點(即或)通過收集節點(即)

public class Project 
    { 
     public string Name { get; set; } 
     public List<Message> MessageCollection = new List<Message>(); 

     public void LoadFromXml(string xmlString) 
     { 
      // From System.Xml.Linq 
      XDocument xDocument = XDocument.Parse(xmlString); 

      // The following assumes your XML is well formed, is not missing attributes and has no type conversion problems. In 
      // other words, there is (almost) zero error checking. 
      if (xDocument.Document != null) 
      { 
       XElement projectElement = xDocument.Element("Project"); 

       if (projectElement != null) 
       { 
        Name = projectElement.Attribute("Name") == null ? "Untitled Project" : projectElement.Attribute("Name").Value; 

        MessageCollection = new List<Message> 
         (from message in xDocument.Element("Project").Elements("Messages") 
         select new Message() 
           { 
            Name = message.Attribute("Name").Value, 
            BitfieldCollection = new List<BitField> 
             (from bitField in message.Elements("Bitfields") 
              select new BitField() {High = int.Parse(bitField.Attribute("High").Value), Low = int.Parse(bitField.Attribute("Low").Value)}) 
           } 
         ); 
       } 
      } 
     } 
    } 

    public class Message 
    { 
     public string Name { get; set; } 
     public List<BitField> BitfieldCollection = new List<BitField>(); 
    } 

    public class BitField 
    { 
     public int High { get; set; } 
     public int Low { get; set; } 
     public List<string> ValueCollection = new List<string>(); 
    } 
1

你一定要牢記模型的分離包圍以及該模型的視圖和外部表示。根據實際的XML的大小以及這種類型的API可以讓你感覺舒適,可以使用幾種完全不同的方式來讀取XML並將其轉換爲實際的對象,然後將其作爲您的UI的模型。牢記這種分離很重要。

我會假定你的XML是來自其他處理的實際數據 - 這意味着將會有很多項目標籤,有很多消息標籤,並且位域跨度不同於消息。如果這個假設是錯誤的,並且位域跨度對於整個應用程序或者一個大文件中的所有消息都是固定的,那麼您可以節省一些時間和空間。

因此,假設所有東西都是可變的,那麼從標籤獲取值的最快方法就是創建XPathDocumen並通過XPath進行選擇,然後您可以保留字符串或配置文件。例如,這會給你所有的價值標籤(現稱爲節點)

//Project/Message/BitField/Value 

,並因爲對節點的對象有父指針,你可以去收集共享父(到一個列表或數組)的所有值,則使物體對於父級(BitField),保留它並確保它具有來自XmlNode的Parent指針。一旦你擁有了所有的BitField對象,你就可以進行類似的掃描,然後分組到他們的父母(Message)中,並再次獲得Project-s。這只是一種方法,您可以使用較短的XPath來說明從BitField開始收集並自行獲取子項。

您還可以製作一些普通類來逐字表示XML標記(每個字段一個數據成員,每個標記一個類),然後爲XmlSerialization設置屬性。這將需要一些試驗來確定名稱是否正確,但是你可以通過函數調用來「反序列化」整個文件,並從.NET接收數組或數組的數組:。

如果您的文件非常非常大,那麼您可能必須使用XmlTextReader並從上到下掃描文件 - 與XPath選擇完全相反(XmlTextReader是解析的最輕方式,不會創建噸的額外的對象,但你必須在幾個外觀上迭代它,並且總是從父母到孩子「走路」,因爲它是單向的)。

如果您有時間進行UI實驗,可能值得嘗試構建一個包含3個組合框和一個文本框然後列出這些框的邊界框 - 以便您擁有更大的靈活性,例如:不必遵守電網的機制。

哦,如果您對XML格式有任何影響,嘗試讓ppl始終將該值放入值標記中,即使它只是一個。 XML文件將會更長一些,但是您的處理將會簡化。

1

這可以使用數據綁定和XMLReaders完成。首先創建你的用戶界面,最好在父面板內部(這樣我們可以設置面板的數據上下文,而子控件將全部繼承這個上下文)。

接下來創建一個自定義類(我們稱之爲Project)。確保此類中的每個字段都更新PropertyDependencyInfo,否則數據綁定將無法工作。

然後將UI控件的Content或Itemssource屬性綁定到Project類的字段。

然後,使用XMLReader類或XPathReader類創建讀取XML的代碼。然後,當您訪問文件中的數據時,設置一個新的Project對象的字段以匹配您想要讀取的數據。

一旦Project對象已被實例化並且XML的值正確地分配給它,請將父級Panel從UI的DataContext屬性設置爲您的Project對象。所有的UI字段都應該更新。

如果您隨後需要加載不同的文件,您只需使用不同的文件名重複XML讀取。

至於你的更新:行和列可以使用管理以下任一操作:

表格/ UniformGrid控制其RowDefinition和ColumnDefinition兒童創建並在運行時修改,以管理增加和減少的數目字段

或者:一組StackPanel,每列一列(因爲列數永遠不會改變)。您可以直接將組合框添加到您的值/ @名稱列的StackPanel,或者您可以修改StackPanel的ItemsTemplate(如果它有一個,我無法到達機器以檢查此刻)。

這個問題應該可以分成幾個子問題,因爲它涵蓋了一系列的主題,如果有問題專門針對這些問題定製問題,那麼您更可能得到問題每個方面的詳細答案。