WPF XAML数据绑定

细节

我已经玩了一段时间了,虽然我可以正确绑定我的设计时数据,但似乎无法绑定运行时数据。我花了很多时间在网上查看许多示例,以各种方式介绍数据绑定的方法,但是还没有碰到任何这样做的方法。

我的想法是使用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;
    }
}

小部件数据保持不变。

费德里科·贝拉萨特吉(Federico Berasategui)

快速解决方案:

在您的构造函数中交换以下各行的顺序:

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

真正的解决方案:

创建一个适当的ViewModel来实现INotifyPropertyChanged绑定,而不是将窗口绑定到自身。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

WPF数据绑定到XAML

来自分类Dev

数据绑定到组合框WPF XAML

来自分类Dev

wpf使用XAML的数据绑定不起作用

来自分类Dev

WPF xaml:无法使用本地绑定数据

来自分类Dev

如何显示数据绑定或重写ToString()C#WPF XAML

来自分类Dev

如何使用 PowerShell 执行 WPF/XAML 的数据绑定

来自分类Dev

XAML WPF的绑定/引用方法

来自分类Dev

WPF XAML绑定不会更新

来自分类Dev

WPF数据绑定混乱

来自分类Dev

Tabcontol -wpf的数据绑定

来自分类Dev

WPF MVVM数据绑定

来自分类Dev

#c Wpf 数据绑定

来自分类Dev

在WPF和XAML和数据绑定的设计视图中查看UI更改吗?

来自分类Dev

直接在xaml / wpf中将特定的数据库字段绑定到文本框

来自分类Dev

在使用WPF和XAML以及数据绑定的设计视图中查看UI更改吗?

来自分类Dev

在WPF中的XAML中,将数据从XmlDataProvider绑定到ListBox失败

来自分类Dev

XAML中的WPF ListView绑定ItemsSource

来自分类Dev

XAML中的WPF文本块绑定

来自分类Dev

不使用XAML进行绑定[WPF]

来自分类Dev

WPF-MVVM-XAML绑定问题

来自分类Dev

WPF xaml DataTrigger绑定不起作用

来自分类Dev

WPF / XAML绑定:使用实际的DataContext

来自分类Dev

不使用XAML进行绑定[WPF]

来自分类Dev

WPF XAML 尝试绑定 DataGrid 列的宽度

来自分类Dev

使用 INotifyPropertyChanged 的 WPF Xaml 绑定类实例

来自分类Dev

wpf xaml 如何将元素名称数据选择器绑定到其他数据选择器

来自分类Dev

使用ComboBox的WPF数据绑定

来自分类Dev

奇怪的WPF数据绑定行为

来自分类Dev

WPF中的琐碎数据绑定