2010-07-09 126 views
1

問候鄉親們! 我遇到了一個WPF數據綁定問題,我希望你能幫忙。我是新來的WPF,但一個expereienced開發人員(VB 3.0-6.0,C#)。XAML內聯數據綁定不起作用;綁定作品背後的代碼

這裏是場景: 我有一個名爲MasterPartsData的C#項目,其中包含了許多不同類型的部件(電容器,二極管等)的類。它們從一個名爲clsPart的基類繼承而來。我有另一個C#WPF項目,其中包含WPF UserControls(以及一個MainWindow),以直觀地表示存儲在一個單獨的MasterPartsData(MPD)對象中的值。我在usercontrol中創建了一個私有字段,用getter和setter來保存對象。

如果我創建在設定器的結合顯式填充的對象:

_capacitor = value; 
Binding binding = new Binding(); 
binding.Source = _capacitor; 
binding.Path = new PropertyPath("C0uf"); 
this.txtC0uf.SetBinding(TextBox.TextProperty, binding); 

(與_capacitor作爲私有對象變量和C0uf爲屬性名) 值正確顯示。

但是我不希望在後面的代碼中明確創建每個綁定。我的首選是在XAML中內聯創建綁定,也許使用指向該對象的DataContext。

不幸的是,我試過的每一個不同的排列都失敗了;該文本框不顯示數據。

我有幾個懷疑: 1)綁定是正確的,但文本框需要刷新。 2)綁定混淆了私有變量和屬性。 3)也許類在不同的項目中定義的事實是造成問題。 4)我生氣了,應該在有人受傷前檢查自己進入庇護所。 :)

任何幫助,您可以提供將不勝感激。我非常樂意添加更多信息,但並不希望將問題與頁面和源代碼頁面混淆起來。

回答

4

對於您的懷疑:

1)我認爲TextBox的默認綁定行爲是TwoWay,具有LostFocus更新觸發,這意味着你的UI重點將收到切換到另一個控制的結合將更新,如果在UI中進行更改。

如果在代碼中進行更改,則需要提升NotifyPropertyChanged事件以便綁定系統查看它。

2)這可能不是這種情況,但它給人留下的印象是你試圖在你的UserControl屬性上設置綁定,這不是數據綁定被設計用於這種特殊用例的方式。你想要的是將non-UI類的數據綁定到UserControl上的依賴項屬性。

3)只要你的UI項目有你的類的引用,這永遠不會有問題。

4)這是人們在開始使用XAML和WPF時常見的反應。這就好像不是交了一箱樂高玩具,而是交給了一臺沒有足夠指令的注塑機,不是嗎?總的來說,這是一種情況,你可能需要檢查你的設計; 「Model-View-ViewModel」模式的元素將派上用場。如果您對此不熟悉,那麼您會在其中引入一個「ViewModel」類的開發模式,也許您可​​以將其稱爲MasterPartsVM,其中包含INotifyPropertyChanged的實現。

UserControlDataContext將設置爲此類MasterPartsVM類。

一個簡短的代碼示例,使用一些通用名稱。給定一個ViewModel類的小支持類,看起來像這樣:

class PartViewModel : INotifyPropertyChanged 
{ 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    public PartClass Data { get; set; } 

    public String SomeVMProperty 
    { 
     get { return Data.SomeProperty; } 

     set 
     { 
      if (Data.SomeProperty != value) 
       Data.SomeProperty = value; 
      this.PropertyChanged(this, new PropertyChangedEventArgs("SomeVMProperty")); 
     } 
    } 

} 

class PartClass 
{ 
    public string SomeProperty { get; set; } 
} 

一個基本的用戶控件的XAML應該是這樣的:

<UserControl x:Class="WpfApplication1.PartUserControl" 
      ... > 
    <Grid> 
     <TextBox Text="{Binding SomeVMProperty}" Margin="68,77,104,176" /> 
    </Grid> 
</UserControl> 

要將數據類連接到這個用戶控件,設置UserControl的DataContext屬性。如果你這樣做的代碼,它是有你的用戶控件的引用和視圖模型,然後設置屬性的問題:

MyUserControlInstance.DataContext = new PartViewModel(); // or some existing PartViewModel 

的代碼組合應努力產生一個文本框,其Text財產變化,每時間SomeVMProperty屬性已更改。

+0

非常感謝您提供的信息!我開始看到ModelView在哪裏發揮作用。在我的情況下,我有一個包含多個其他類的對象。 ModelView本質上給出了層次結構的'平面'視圖,所以XAML只有一個數據上下文來處理。正確? – Falconeer 2010-07-12 16:02:15

+0

或多或少正確,但MVVM模式仍然只是一種模式;在執行該模式的數據綁定合同中沒有任何固有的東西。在層次結構中,您可以爲用戶控件的子元素指定其他數據上下文,這可能會破壞良好的架構理念。對我而言,使ViewModel具有處理數據綁定細節(雙向或單向,以及站點轉換器的地方)的一點並不需要您修改模型中的代碼。 – 2010-07-12 17:36:06

1

在基本約束的情況下,如果你的類看起來像這樣

public class MasterPartsData 
{ 
    private string _c0uf; 

    public string C0uf 
    { 
     get { return _c0uf;} 
     set { _c0uf = value;} 
    } 

    public MasterPartsData() 
    { 
     C0uf = "Hello World!"; 
    } 
} 

您的XAML看起來像這樣

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="MainWindow" > 
    <Window.DataContext> 
     <local:MasterPartsData /> 
    </Window.DataContext> 

    <Grid> 
     <TextBlock Text="{Binding Path=C0uf}" /> 
    </Grid> 
</Window> 

注意,有很多不同的方法來設置DataContext的,你不併不一定只需要在XAML中執行此外,通常您的MasterDataParts類將實現INotifyPropertyChanged