WPF:在 XAML 中设置 ItemSource 与代码隐藏

发布于 2024-08-19 07:50:16 字数 1775 浏览 1 评论 0原文

由于这是 WPF,它可能看起来有很多代码,但不要害怕,问题非常简单!

我有以下 XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:hax="clr-namespace:hax" x:Class="hax.MainWindow"
    x:Name="Window" Title="Haxalot" Width="640" Height="280">

    <Grid x:Name="LayoutRoot">
        <ListView ItemsSource="{Binding AllRoles}" Name="Hello">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                       DisplayMemberBinding="{Binding Path=FullName}"/>
                    <GridViewColumn Header="Role"
                       DisplayMemberBinding="{Binding Path=RoleDescription}"/>
                </GridView>
            </ListView.View>
        </ListView> 
    </Grid>
</Window>

我有以下代码隐藏:

using System.Collections.ObjectModel;
using System.Windows;

namespace hax
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public ObservableCollection<Role> AllRoles { get { return m_AllRoles; } set { m_AllRoles = value; } }
        private ObservableCollection<Role> m_AllRoles = new ObservableCollection<Role>();

        public MainWindow()
        {
            this.InitializeComponent();

            AllRoles.Add(new Role("John", "Manager"));
            AllRoles.Add(new Role("Anne", "Trainee"));
            // Hello.ItemsSource = AllRoles; // NOTE THIS ONE!
        }
    }
}

如果我将语句 Hello.ItemSource = AllRoles 注释掉,网格将不显示任何内容。当我把它放回去时,它会显示正确的内容。这是为什么呢?

Since this is WPF, it may look like lots of code, but don't be frightened, the question is really simple!

I have the following XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:hax="clr-namespace:hax" x:Class="hax.MainWindow"
    x:Name="Window" Title="Haxalot" Width="640" Height="280">

    <Grid x:Name="LayoutRoot">
        <ListView ItemsSource="{Binding AllRoles}" Name="Hello">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name"
                       DisplayMemberBinding="{Binding Path=FullName}"/>
                    <GridViewColumn Header="Role"
                       DisplayMemberBinding="{Binding Path=RoleDescription}"/>
                </GridView>
            </ListView.View>
        </ListView> 
    </Grid>
</Window>

I have this code-behind:

using System.Collections.ObjectModel;
using System.Windows;

namespace hax
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public ObservableCollection<Role> AllRoles { get { return m_AllRoles; } set { m_AllRoles = value; } }
        private ObservableCollection<Role> m_AllRoles = new ObservableCollection<Role>();

        public MainWindow()
        {
            this.InitializeComponent();

            AllRoles.Add(new Role("John", "Manager"));
            AllRoles.Add(new Role("Anne", "Trainee"));
            // Hello.ItemsSource = AllRoles; // NOTE THIS ONE!
        }
    }
}

If I leave the statement Hello.ItemSource = AllRoles commented out, the grid displays nothing. When I put it back in, it displays the correct thing. Why is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朱染 2024-08-26 07:50:16

This:

<ListView ItemsSource="{Binding AllRoles}" Name="Hello">

表示“将 ItemsSource 绑定到属性 this.DataContext.AllRoles”,其中 this 是当前元素。

Hello.ItemsSource = AllRoles;

表示“将 ItemsSource 绑定到充满角色的 ObservableCollection”,它直接执行您最初尝试执行的操作。

在 xaml 中有多种方法可以实现此目的。这是一个:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        var allRoles = new ObservableCollection<Role>()
        allRoles.Add(new Role("John", "Manager"));
        allRoles.Add(new Role("Anne", "Trainee"));
        this.DataContext = allRoles;
    }
}

在 xaml 中

<ListView ItemsSource="{Binding}" Name="Hello">

或者,,您可以将 AllRoles 设为窗口的公共属性

public partial class MainWindow : Window
{
    public ObservableCollection<Role> AllRoles {get;private set;}
    public MainWindow()
    {
        this.InitializeComponent();
        var allRoles = new ObservableCollection<Role>()
        allRoles.Add(new Role("John", "Manager"));
        allRoles.Add(new Role("Anne", "Trainee"));
        this.AllRoles = allRoles;
    }
}

,然后使用relativesource告诉绑定沿着逻辑树向上走到窗口,

<ListView 
  ItemsSource="{Binding AllRoles, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 
  Name="Hello">

这意味着“看”在我的祖先中,直到找到一个窗口,然后在窗口上查找名为 AllRoles 的公共属性”。

但最好的方法是完全跳过该死的代码隐藏并使用 MVVM 模式. 如果您正在学习,我建议您直接跳到 MVVM 模式。学习曲线很陡峭,但您可以了解有关绑定和命令的所有内容以及有关 WPF 的重要、酷炫的内容。

This:

<ListView ItemsSource="{Binding AllRoles}" Name="Hello">

means "Bind ItemsSource to the property this.DataContext.AllRoles" where this is the current element.

Hello.ItemsSource = AllRoles;

means "Bind ItemsSource to an ObservableCollection<T> full of roles", which directly does what you were trying to do originally.

There are a number of ways to do this in xaml. Here's one:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        var allRoles = new ObservableCollection<Role>()
        allRoles.Add(new Role("John", "Manager"));
        allRoles.Add(new Role("Anne", "Trainee"));
        this.DataContext = allRoles;
    }
}

and in the xaml

<ListView ItemsSource="{Binding}" Name="Hello">

OR, alternatively, you could make AllRoles a public property of the window

public partial class MainWindow : Window
{
    public ObservableCollection<Role> AllRoles {get;private set;}
    public MainWindow()
    {
        this.InitializeComponent();
        var allRoles = new ObservableCollection<Role>()
        allRoles.Add(new Role("John", "Manager"));
        allRoles.Add(new Role("Anne", "Trainee"));
        this.AllRoles = allRoles;
    }
}

and then use a RelativeSource to tell the Binding to walk up the logical tree to the Window

<ListView 
  ItemsSource="{Binding AllRoles, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 
  Name="Hello">

Which means "Look at my ancestry until you find a Window, then look for a public property on the window called AllRoles".

But the best way to do this is to skip the frigging codebehind altogether and use the MVVM pattern. I'd suggest if you're learning that you skip directly to the MVVM pattern. The learning curve is steep, but you learn all about binding and commands and the important, cool things about WPF.

念﹏祤嫣 2024-08-26 07:50:16

当您绑定到 WPF 中的数据源时,它会查找窗口数据上下文中名为“AllRoles”的属性。查看模型-视图-视图模型模式,了解有关 xaml 中数据绑定的更多信息。
http://msdn.microsoft.com/en-us/magazine/dd419663。 ASPX

When you bind to a datasource in WPF, it is looking for a property of your Window's data context called "AllRoles". Check out the Model-View-ViewModel pattern for more on data binding in xaml.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文