WPF: Setting ItemSource in XAML vs. code-behind

情到浓时终转凉″ 提交于 2019-12-09 03:14:07

问题


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?


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/2147559/wpf-setting-itemsource-in-xaml-vs-code-behind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!