WPF: установка ItemSource в XAML по сравнению с выделенным кодом

Так как это 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 закомментированным, сетка не отобразит ничего. Когда я вставляю его обратно, он показывает правильную вещь. Почему это?


person Deniz Dogan    schedule 27.01.2010    source источник


Ответы (2)


Этот:

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

означает «Привязать ItemsSource к свойству this.DataContext.AllRoles», где this — текущий элемент.

Hello.ItemsSource = AllRoles;

означает «Привязать ItemsSource к ObservableCollection<T>, полному ролей», что напрямую делает то, что вы пытались сделать изначально.

В 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, чтобы указать Binding подняться по логическому дереву к Window

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

Это означает: «Посмотрите на мою родословную, пока не найдете окно, а затем найдите общедоступное свойство в окне с именем AllRoles».

Но лучший способ сделать это — вообще пропустить этот чертов программный код и использовать шаблон MVVM. . Если вы учитесь, я бы посоветовал сразу перейти к шаблону MVVM. Кривая обучения крутая, но вы узнаете все о связывании и командах, а также о важных и интересных вещах в WPF.

person Community    schedule 27.01.2010

Когда вы привязываетесь к источнику данных в WPF, он ищет свойство контекста данных вашего окна, называемое «AllRoles». Ознакомьтесь с шаблоном Model-View-ViewModel, чтобы узнать больше о привязке данных в xaml. http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

person Steve Danner    schedule 27.01.2010