2015-08-28 138 views
0

我一直在玩这一段时间,虽然我可以让我的设计时间数据正确绑定,我似乎无法得到运行时数据绑定。我花了很长时间在网上查看了很多关于数据绑定方式的例子,但还没有遇到任何这样做的例子。WPF XAML数据绑定

我的想法是,窗口绑定到自己使用RelativeSource,然后应该允许我绑定网格的窗口,即MyWidget的属性。我想我已经与我的设计时间,数据复制这一点,所以我真的不知道为什么设计师的作品,但是当我运行它,我只是得到了一个空白窗口...

这里是我的XAML窗口:

<Window x:Class="XamlPrototype.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:XamlPrototype" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="646" Width="344" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    d:DataContext="{Binding Source={d:DesignInstance Type=local:DesignTimeWidgetData, IsDesignTimeCreatable=True}}"> 
<Grid x:Name="MyGrid" 
     DataContext="{Binding MyWidget}"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="50" /> 
     <RowDefinition Height="20" /> 
     <RowDefinition Height="10" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock FontSize="20" VerticalAlignment="Center" FontWeight="Medium" Grid.Row="0" Margin="20,20,0,0" Text="{Binding Title}" /> 
    <TextBlock FontSize="12" VerticalAlignment="Top" Grid.Row="1" Margin="20,0,0,0" Text="{Binding Subtitle}" /> 
    <StackPanel Grid.Row="3"> 
     <ItemsControl 
      x:Name="ItemsControl" 
      ItemsSource="{Binding Items}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal" Margin="20,20,0,0"> 
         <Rectangle Stroke="Red" StrokeThickness="5" Width="25" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,0,0"></Rectangle> 
         <TextBlock FontSize="20" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10,0,0,5" Text="{Binding}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
</Grid> 

..its代码后面:

public partial class MainWindow : Window 
{ 
    public Widget MyWidget { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     InitializeWidgetData(); 
    } 

    private void InitializeWidgetData() 
    { 
     MyWidget = new Widget 
     { 
      Title = "This is the Title", 
      Subtitle = "This is the subtitle", 
      Items = new List<string> 
      { 
       "Item Short Name 1", 
       "Item Short Name 2", 
       "Item Short Name 3", 
       "Item Short Name 4", 
       "Item Short Name 5", 
       "Item Short Name 6", 
       "Item Short Name 7", 
       "Item Short Name 8" 
      } 
     }; 
    } 
} 

数据上下文:

public class Widget 
{ 
    public string Title { get; set; } 
    public string Subtitle { get; set; } 
    public List<string> Items { get; set; } 
} 

和我的设计时数据:

public class DesignTimeWidgetData 
{ 
    public Widget MyWidget { get; set; } 

    public DesignTimeWidgetData() 
    { 
     MyWidget = new Widget 
     { 
      Title = "Design Time Title", 
      Subtitle = "Design Time Subtitle", 
      Items = new List<string> 
      { 
       "Design Time Short Name 1", 
       "Design Time Short Name 2", 
       "Design Time Short Name 3", 
       "Design Time Short Name 4", 
       "Design Time Short Name 5", 
       "Design Time Short Name 6", 
       "Design Time Short Name 7", 
       "Design Time Short Name 8" 
      } 
     }; 
    } 
} 

UPDATE:

继HighCore的建议和例子,我一点额外的谷歌搜索,我修改了项目如下:

App XAML:

<Application x:Class="XamlPrototype.App" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:XamlPrototype" 
     StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <local:WindowViewModel x:Key="WindowViewModel" /> 
</Application.Resources> 

的窗口XAML:

<Window x:Class="XamlPrototype.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:XamlPrototype" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="646" Width="344"   
    DataContext="{StaticResource WindowViewModel}" 
    d:DataContext="{Binding Source={d:DesignInstance Type=local:DesignTimeViewModel, IsDesignTimeCreatable=True}}"> 
<Grid x:Name="MyGrid"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="50" /> 
     <RowDefinition Height="20" /> 
     <RowDefinition Height="10" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock FontSize="20" VerticalAlignment="Center" FontWeight="Medium" Grid.Row="0" Margin="20,20,0,0" Text="{Binding WindowTitle}" /> 
    <TextBlock FontSize="12" VerticalAlignment="Top" Grid.Row="1" Margin="20,0,0,0" Text="{Binding WindowSubtitle}" /> 
    <StackPanel Grid.Row="3"> 
     <ItemsControl 
      x:Name="ItemsControl" 
      ItemsSource="{Binding WindowItems}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal" Margin="20,20,0,0"> 
         <Rectangle Stroke="Red" StrokeThickness="5" Width="25" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,0,0"></Rectangle> 
         <TextBlock FontSize="20" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10,0,0,5" Text="{Binding}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
</Grid> 

..和其后面的代码:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 
} 

的视图模型:

public class WindowViewModel : INotifyPropertyChanged 
{ 
    private Widget _widget; 

    public string WindowTitle 
    { 
     get { return _widget.Title ?? "Error!"; } 
    } 

    public string WindowSubtitle 
    { 
     get { return _widget.Subtitle ?? "Error!"; } 
    } 

    public List<string> WindowItems 
    { 
     get { return _widget.Items ?? new List<string>(); } 
    } 

    public WindowViewModel() 
    { 
     //in reality this would come from the Db, or a service perhaps.. 
     _widget = new Widget 
     { 
      Title = "This is the Title", 
      Subtitle = "This is the subtitle", 
      Items = new List<string> 
      { 
       "Item Short Name 1", 
       "Item Short Name 2", 
       "Item Short Name 3", 
       "Item Short Name 4", 
       "Item Short Name 5", 
       "Item Short Name 6", 
       "Item Short Name 7", 
       "Item Short Name 8" 
      } 
     }; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void RaisePropertyChanged(string propertyName) 
    { 
     // take a copy to prevent thread issues 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

设计时间(视图模型)数据:

public class DesignTimeViewModel 
{ 
    public string WindowTitle { get; set; } 
    public string WindowSubtitle { get; set; } 
    public List<string> WindowItems { get; set; } 

    public DesignTimeViewModel() 
    { 
     var widget = new Widget 
     { 
      Title = "Design Time Title", 
      Subtitle = "Design Time Subtitle", 
      Items = new List<string> 
      { 
       "Design Time Short Name 1", 
       "Design Time Short Name 2", 
       "Design Time Short Name 3", 
       "Design Time Short Name 4", 
       "Design Time Short Name 5", 
       "Design Time Short Name 6", 
       "Design Time Short Name 7", 
       "Design Time Short Name 8" 
      } 
     }; 

     WindowTitle = widget.Title; 
     WindowSubtitle = widget.Subtitle; 
     WindowItems = widget.Items; 
    } 
} 

控件数据保持不变。

回答

2

快速解决方案:

掉在你的构造这些线的顺序:

public MainWindow() 
{ 
    InitializeWidgetData(); // This first 
    InitializeComponent(); // This second 
} 

真正的解决办法:

创建一个实现INotifyPropertyChanged绑定到一个适当的视图模型,而不是将窗口绑定到自己。

+0

您能举一个真实解决方案的例子吗? – Detail

+0

http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial –