2013-03-04 65 views
0

我是WPF的新手,我正試圖理解如何使用數據綁定將我的窗口上的控件綁定到我代碼背後的對象。我從代碼隱藏中看到了有關訪問XAML對象的幾個問題,但這不是我正在尋找的。我已經知道如何做到這一點。如何從XAML中訪問代碼中的對象

label1.Content = LabelText; 
listbox1.ItemsSource = ListItems; 

我也看到了有關如何從XAML訪問代碼隱藏類的答案。

<local:MyClass x:Key="myClass" /> 

但我不明白如何將其應用於該類的特定實例。這是我想要做的一個例子。 '綁定'顯然是不正確的。這是我需要幫助的。

public partial class MainWindow : Window 
{ 
    private string _labelText; 
    private List<string> _listItems = new List<string>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 

     _labelText = "Binding"; 
     _listItems.Add("To"); 
     _listItems.Add("An"); 
     _listItems.Add("Object"); 
    } 

    public string LabelText 
    { 
     get { return _labelText; } 
     set { _labelText = value; } 
    } 

    public List<string> ListItems 
    { 
     get { return _listItems; } 
     set { _listItems = value; } 
    } 
} 

<Window x:Class="SO_Demo.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="SO Demo" Height="160" Width="225"> 
    <Grid DataContext="MainWindow"> 
    <Label x:Name="label1" Width="80" Height="25" Margin="12,12,0,0" 
      Content="{Binding Path=LabelText}" 
      HorizontalAlignment="Left" VerticalAlignment="Top" /> 
    <ListBox x:Name="listbox1" Width="100" Height="60" Margin="12,44,0,0" 
      ItemsSource="{Binding Path=ListItems}" DisplayMemberPath="ListItems" 
      HorizontalAlignment="Left" VerticalAlignment="Top" /> 
    </Grid> 
</Window> 

我讀過的書和教程使它聽起來像這樣應該很簡單。我錯過了什麼?

回答

2

雖然您可以直接DataBind在你嘗試的方式類,它是不是如何這通常是完成的。建議的方法是創建一個對象(ViewModel),用於彙總所有要在UI中顯示的模型數據,然後將該ViewModel設置爲您的視圖的DataContext(本例中爲Window)。我會推薦閱讀關於MVVM,這是大多數WPF應用程序的構建。但下面的例子可以讓你開始。

在這裏是根據你的樣品上方的簡單示例:

視圖模型

public class MyViewModel : INotifyPropertyChanged 
{ 
    private string _title; 
    private ObservableCollection<string> _items; 

    public string LabelText 
    { 
     get { return _title; } 
     set 
     { 
      _title = value; 
      this.RaisePropertyChanged("Title"); 
     } 
    } 

    public ObservableCollection<string> ListItems { 
     get { return _items; } 
     set 
     { 
      _items = value; //Not the best way to populate your "items", but this is just for demonstration purposes. 
      this.RaisePropertyChanged("ListItems"); 
     } 
    } 

    //Implementation of INotifyPropertyChanged 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

} 

代碼隱藏

public partial class MainWindow : Window 
{ 
    private MyViewModel _viewModel; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     _viewModel = new MyViewModel(); 

     //Initialize view model with data... 

     this.DataContext = _viewModel; 
    } 
} 

視圖(窗口)

<Window x:Class="SO_Demo.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="SO Demo" Height="160" Width="225"> 
    <Grid> 
    <Label x:Name="label1" Width="80" Height="25" Margin="12,12,0,0"    Content="{Binding Path=LabelText}" 
      HorizontalAlignment="Left" VerticalAlignment="Top" /> 
    <ListBox x:Name="listbox1" Width="100" Height="60" Margin="12,44,0,0" 
      ItemsSource="{Binding Path=ListItems}" 
      HorizontalAlignment="Left" VerticalAlignment="Top" /> 
    </Grid> 
</Window> 
+0

這有助於很多!我想我記得在某處閱讀source屬性(和target?)必須是依賴屬性。真的嗎?謝謝! – JNygren 2013-03-04 22:28:34

+0

幾乎 - 你已經倒退了。 Source屬性可以是任何公共屬性。使用INotifyPropertyChanged接口,以便對源的更新將自動反映到目標中。 Target需要成爲'DependencyProperty'。 [此MSDN主題](http://msdn.microsoft.com/en-us/library/ms752347.aspx#creating_a_binding)詳細描述了「DataBinding」,並詳細說明了源和目標。 – 2013-03-04 22:51:42

3

<Grid DataContext="MainWindow">無效。

如果你要引用的窗口,你必須:

<Window x:Name="MyWindow"> 
    <Grid DataContext="{Binding ElementName=MyWindow}"/> 
</Window> 

<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> 
+0

並且'DisplayMemberPath =「ListItems」'應從列表框中移除。沒有用。 – Clemens 2013-03-04 21:57:07

+0

而屬性將需要'INotifyPropertyChanged'語義。 – user7116 2013-03-04 21:59:52

+0

好的,那麼'ListItems'也可能是'ObservableCollection '(或者至少實現'INotifyCollectionChanged'):-) – Clemens 2013-03-04 22:01:38

相關問題