WPF: настройка ItemSource в XAML или выделение кода - PullRequest
6 голосов
/ 27 января 2010

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

Ответы [ 2 ]

15 голосов
/ 27 января 2010

Это:

<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 для перехода по логическому дереву к окну

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

Что означает: «Посмотри на мою родословную, пока не найдешь Окно, а затем найди открытое свойство в окне под названием AllRoles».

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

0 голосов
/ 27 января 2010

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

...