我已经玩了一段时间了,虽然我可以正确绑定我的设计时数据,但似乎无法绑定运行时数据。我花了很多时间在网上查看许多示例,以各种方式介绍数据绑定的方法,但是还没有碰到任何这样做的方法。
我的想法是使用RelativeSource将Window绑定到其自身,然后应该允许我将网格绑定到Window的属性,即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>
..其背后的代码:
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"
}
};
}
}
更新:
遵循HighCore的建议和示例,并增加了一些Google搜索,我对项目进行了如下修改:
应用程序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>
Window 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();
}
}
ViewModel:
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));
}
}
}
设计时间(viewmodel)数据:
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;
}
}
小部件数据保持不变。
快速解决方案:
在您的构造函数中交换以下各行的顺序:
public MainWindow()
{
InitializeWidgetData(); // This first
InitializeComponent(); // This second
}
真正的解决方案:
创建一个适当的ViewModel来实现INotifyPropertyChanged
绑定,而不是将窗口绑定到自身。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句