【问题标题】:WPF: Setting ItemSource in XAML vs. code-behindWPF:在 XAML 与代码隐藏中设置 ItemSsource
【发布时间】:2010-01-27 14:26:08
【问题描述】:

由于这是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 注释掉,网格将显示 nothing。当我把它放回去时,它会显示正确的东西。这是为什么呢?

【问题讨论】:

    标签: c# wpf listview itemssource


    【解决方案1】:

    这个:

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

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

    Hello.ItemsSource = AllRoles;
    

    意思是“将ItemsSource绑定到一个充满角色的ObservableCollection&lt;T&gt;”,它直接做了你最初想做的事情。

    在 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 pattern.,如果您正在学习直接跳到 MVVM 模式,我建议您这样做。学习曲线很陡峭,但您将了解所有关于绑定和命令以及有关 WPF 的重要而酷的东西。

    【讨论】:

      【解决方案2】:

      当您绑定到 WPF 中的数据源时,它会查找您的 Window 数据上下文的属性,称为“AllRoles”。查看 Model-View-ViewModel 模式,了解有关 xaml 中数据绑定的更多信息。 http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-21
        • 1970-01-01
        • 2013-09-18
        • 2021-12-18
        • 1970-01-01
        • 2012-07-15
        • 2012-03-30
        • 1970-01-01
        相关资源
        最近更新 更多