WPF里如何在ListView中绑定并显示数据

诚实可爱的小郎君 2017-09-21 02:00:40
<DataTemplate >
<ListView Margin="1"
BorderThickness="1"
SelectedIndex="0"
ItemsSource="{Binding printJobs}"
Style="{StaticResource VirtualisedMetroListView}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding viewModel.printJobs.JobID}" Header="作业编号" Width="50" />
<GridViewColumn DisplayMemberBinding="{Binding viewModel.printJobs.JobName}" Header="作业名称" Width="400"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>

这里不要在ListView中设置Name属性然后再后台添加,我就想知道设置了ItemsSource后如何取得源数据后显示在前台
...全文
1442 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
想请教一下你,是否有办法可以通过控件名获得DataTemplate内部的控件对象
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复
你这是在自定义模板了,试下 ItemsSource="{Binding DataContext.PrintJobs, Mode=OneWay}, Name就不用改了 用实时属性查看器看下实际的ItemSource是什么,具体代码调试要你自己调了,如果绑定后没有任何数据,一般是你赋值的DataContext里没找到你绑定的source
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复
HamburgerMenu没用过,貌似是找不到DataContext,你检查下你的代码。或者试下

<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="名称" Width="400"/>
改成
<GridViewColumn DisplayMemberBinding="{Binding DataContext.Name}" Header="名称" Width="400"/>

运行时你还可以查看下具体指

  • 打赏
  • 举报
回复

这里在<ListView Margin="0 0 0 0" BorderThickness="1" SelectedIndex="0" ItemsSource="{Binding PrintJobs}" Style="{StaticResource VirtualisedMetroListView}">
绑定的时候就有问题,好像没有绑定成功吧,然后我把Binding里面改成Binding Source=PrintJobs之后是类似于文字透明的那种列表,有选中效果,但是没有文字

你说的那个将
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="名称" Width="400"/>
改成
<GridViewColumn DisplayMemberBinding="{Binding DataContext.Name}" Header="名称" Width="400"/>
我试过了,也是没用,而且我看了一下Binding里面没有DataContext这个属性
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复

ilikeff8 2017-09-22
  • 打赏
  • 举报
回复
你的PrintJobs是怎么定义的
  • 打赏
  • 举报
回复
引用 8 楼 ilikeff8 的回复:
你的PrintJobs是怎么定义的
你的这种方式我也可以做到,只是我用了MahApps.Metro这个插件里面的HamburgerMenu,代码也是上面给你看的那个我一次性给你贴出来吧

           <controls:HamburgerMenu.ContentTemplate>
            <DataTemplate>
                <controls:TransitioningContentControl Grid.Row="1"
                                                              RestartTransitionOnContentChange="True"
                                                              Transition="Default">
                    <controls:TransitioningContentControl.ContentTemplate>
                        <DataTemplate>
                            <ListView  Margin="0 0 0 0" BorderThickness="1" SelectedIndex="0" ItemsSource="{Binding PrintJobs, Mode=OneWay}" Style="{StaticResource VirtualisedMetroListView}">
                                <ListView.View>
                                    <GridView>
                                        <GridViewColumn DisplayMemberBinding="{Binding JobID, Mode=OneWay}" Header="编号" Width="80" />
                                        <GridViewColumn DisplayMemberBinding="{Binding JobName}" Header="名称" Width="400"/>
                                    </GridView>
                                </ListView.View>
                            </ListView>
                        </DataTemplate>
                    </controls:TransitioningContentControl.ContentTemplate>
                </controls:TransitioningContentControl>
            </DataTemplate>
        </controls:HamburgerMenu.ContentTemplate>

 public class PrintJobT
        {
            public UInt64 JobID { get; set; }
            public string JobName { get; set; }
            public PrintJobT()
            { }
            public PrintJobT(UInt64 JobID, string JobName)
            {
                this.JobID = JobID;
                this.JobName = JobName;
            }
        }

        public List<PrintJobT> printJobs;
        public List<PrintJobT> PrintJobs
        {
            get
            {
                return printJobs;
            }
            set
            {
                if (printJobs != value)
                {
                    printJobs = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(PrintJobs)));
                }
            }
        }
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复
引用 4 楼 mx526874883 的回复:
我测试了一下你的代码,在一个.cs里确实是可行的,现在有一个问题就是对于 List<Data> dataList; public List<Data> DataList 这里为何要使用两个list,刚接触C#,对于这里理解的不深入,希望可以解答一下,谢谢
用mvvm模式,不在一个cs里也一样,xaml都不用改

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = new MainViewModel();
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication2
{
    class MainViewModel:INotifyPropertyChanged
    {
        public MainViewModel()
        {

            dataList = new List<Data>
            {
                new Data{Number=1,Name="A"},
                new Data{Number=2,Name="B"}
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public class Data
        {
            public int Number { get; set; }
            public string Name { get; set; }
        }

        List<Data> dataList;
        public List<Data> DataList
        {
            get
            {
                return dataList;
            }
            set
            {
                if (dataList != value)
                {
                    dataList = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataList)));
                }
            }
        }
    }
}

只有一个list,就是dataList DataList是属性,是对dataList的封装,主要是set访问器,当要改变dataList时,顺带调用PropertyChanged通知界面进行更新
  • 打赏
  • 举报
回复
引用 6 楼 ilikeff8 的回复:
[quote=引用 4 楼 mx526874883 的回复:]
我测试了一下你的代码,在一个.cs里确实是可行的,现在有一个问题就是对于
List<Data> dataList;
public List<Data> DataList
这里为何要使用两个list,刚接触C#,对于这里理解的不深入,希望可以解答一下,谢谢



只有一个list,就是dataList
DataList是属性,是对dataList的封装,主要是set访问器,当要改变dataList时,顺带调用PropertyChanged通知界面进行更新
[/quote]


谢谢你的解答,还有一个问题是,我现在在使用MahApps.Metro里面的HamburgerMenu,现在需要有一个问题是

使用你的方法之后这里的ListView的数据并没有更新,下面是xaml的对应段
<controls:HamburgerMenu.ContentTemplate>
<DataTemplate>
<controls:TransitioningContentControl Grid.Row="1"
RestartTransitionOnContentChange="True"
Transition="Default">
<controls:TransitioningContentControl.ContentTemplate>
<DataTemplate>
<ListView Name="MMPNMB" Margin="0 0 0 0" BorderThickness="1" SelectedIndex="0" ItemsSource="{Binding PrintJobs, Mode=OneWay}" Style="{StaticResource VirtualisedMetroListView}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding JobID, Mode=OneWay}" Header="编号" Width="80" />
<GridViewColumn DisplayMemberBinding="{Binding JobName}" Header="名称" Width="400"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</controls:TransitioningContentControl.ContentTemplate>
</controls:TransitioningContentControl>
</DataTemplate>
</controls:HamburgerMenu.ContentTemplate>
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复
<Window x:Class="WpfApplication2.MainWindow" 对应的这个类里 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new MainViewModel(); //设置DataContext, 告诉它哪里去找绑定的source } public MainViewModel() { dataList = new List<Data> { new Data{Number=1,Name="A"}, new Data{Number=2,Name="B"} }; } public event PropertyChangedEventHandler PropertyChanged; public class Data { public int Number { get; set; } public string Name { get; set; } } List<Data> dataList; public List<Data> DataList //找到了 { get { return dataList; } set { if (dataList != value) { dataList = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataList))); } } } 你要检查一下你的代码里的DataContext是怎么赋值的
  • 打赏
  • 举报
回复
引用 14 楼 ilikeff8 的回复:
ItemSource计算值是空的,DataContext不对,wpf没找到PrintJobs
你说的这个DataContext是要在ListView里面设置还是在Window.Resources还是在哪里? 因为刚接触WPF这里的知识也都不连贯,也很匮乏,希望能帮忙解答一下,谢谢了,稍后我会给帖子加分的
ilikeff8 2017-09-22
  • 打赏
  • 举报
回复

ItemSource计算值是空的,DataContext不对,wpf没找到PrintJobs
  • 打赏
  • 举报
回复
引用 1 楼 duanzi_peng 的回复:
DisplayMemberBinding="{Binding viewModel.printJobs.JobID}" -没这样写过,已经指定了ItemsSource,Binding后直接跟数据类的属性名称。
刚开始接触WPF,有的是试着去写的,版主用过MahApps.Metro么?
  • 打赏
  • 举报
回复
引用 2 楼 ilikeff8 的回复:
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView ItemsSource="{Binding DataList}" DisplayMemberPath="Name"/>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;

            dataList = new List<Data>
            {
                new Data{Number=1,Name="A"},
                new Data{Number=2,Name="B"}
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public class Data
        {
            public int Number { get; set; }
            public string Name { get; set; }
        }

        List<Data> dataList;
        public List<Data> DataList
        {
            get
            {
                return dataList;
            }
            set
            {
                if (dataList != value)
                {
                    dataList = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataList)));
                }
            }
        }
    }
}
我测试了一下你的代码,在一个.cs里确实是可行的,现在有一个问题就是对于 List<Data> dataList; public List<Data> DataList 这里为何要使用两个list,刚接触C#,对于这里理解的不深入,希望可以解答一下,谢谢
ilikeff8 2017-09-21
  • 打赏
  • 举报
回复
如果name等发生了改变,需要马上界面反应,就需要类里的属性也设置

public class Data: INotifyPropertyChanged
{
            int number;
            public int Number
            {
                get
                {
                    return number;
                }
                set
                {
                    if (number != value)
                    {
                        number = value;
                        PropertyChanged(this, new PropertyChangedEventArgs(nameof(Number)));
                    }
                }
            }
。。。
如果只是要改变list个数,例如add添加时反映到界面,就用ObservableCollection替代List

        ObservableCollection<Data> dataList;
        public ObservableCollection<Data> DataList
        {
            get
            {
                return dataList;
            }
            set
            {
                if (dataList != value)
                {
                    dataList = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataList)));
                }
            }
        }
如果想省事,想不管是list添加删除记录,还是只是修改某条记录的某个属性,也不想写更多的代码,就统统最后

dataList = new 。。。
ilikeff8 2017-09-21
  • 打赏
  • 举报
回复
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView ItemsSource="{Binding DataList}" DisplayMemberPath="Name"/>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;

            dataList = new List<Data>
            {
                new Data{Number=1,Name="A"},
                new Data{Number=2,Name="B"}
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public class Data
        {
            public int Number { get; set; }
            public string Name { get; set; }
        }

        List<Data> dataList;
        public List<Data> DataList
        {
            get
            {
                return dataList;
            }
            set
            {
                if (dataList != value)
                {
                    dataList = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(DataList)));
                }
            }
        }
    }
}
exception92 2017-09-21
  • 打赏
  • 举报
回复
DisplayMemberBinding="{Binding viewModel.printJobs.JobID}" -没这样写过,已经指定了ItemsSource,Binding后直接跟数据类的属性名称。

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧