【问题标题】:Can static data for Datagrid rows be defined purely in XAML i.e. no code behind?Datagrid 行的静态数据是否可以纯粹在 XAML 中定义,即没有代码?
【发布时间】:2012-05-01 03:03:57
【问题描述】:

我有想要以 Datagrid 格式显示的静态数据。这些值仅用于显示目的,不会更改。是否可以将其添加为 Datagrid 控件的某种子标签,这样我就可以避免代码隐藏中的任何内容?

它必须是 Datagrid 控件,因为其目的是试验和演示某些带有虚拟内容的 Datagrid UI 功能。

如果纯 XAML 内容是不可能的,那么为数据网格设置虚拟内容的最佳(快速和肮脏)方法是什么?不写类等可以吗?

【问题讨论】:

    标签: wpf xaml datagrid wpfdatagrid


    【解决方案1】:

    这是绑定在数据网格上的纯 XAML 静态数据:

    <Window x:Class="WpfStaticDataBinding.XMLWindows"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="XMLWindows" Height="152" Width="294">
    <Window.Resources>
        <XmlDataProvider x:Key="MockList"   XPath="/MockObjects/*" >
            <x:XData >
                <MockObjects xmlns="">
                    <MockObject  Name="Louis" Type="TTTT" Number="1" />
                    <MockObject Name="Joseph" Type="TTTT" Number="2" />
                    <MockObject Name="Papineau" Type="ZZZZ" Number="3" />
                </MockObjects>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>
    <Grid DataContext="{Binding Source={StaticResource MockList}}">
        <DataGrid HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch" 
                  ItemsSource="{Binding Mode=Default, XPath=/MockObjects/MockObject}" 
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding XPath=@Name}" ></DataGridTextColumn>
                <DataGridTextColumn Header="Type" Binding="{Binding XPath=@Type}"></DataGridTextColumn>
                <DataGridTextColumn Header="Number" Binding="{Binding XPath=@Number}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
    

    结果:

    我无法使用 XmlDataProvider 自动生成列(我可能遗漏了一些东西):

    <Grid DataContext="{Binding Source={StaticResource MockList}}">
        <DataGrid HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch" 
                  ItemsSource="{Binding Mode=Default, XPath=/MockObjects/MockObject}">
        </DataGrid>
    </Grid>
    

    但是使用像 Dave Suggestion 这样的代码隐藏类允许 AutoBinding 工作,并且在我看来要简单得多(不过我更喜欢 ResourceDictionary 方法):

    代码:

    namespace WpfStaticDataBinding
    {
        public class MockRecord
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Email { get; set; }
        }
    }
    

    XAML

    <Window x:Class="WpfStaticDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:WpfStaticDataBinding"
        Title="MainWindow" Height="157" Width="302">
    <Window.Resources>
        <ResourceDictionary>
            <x:Array x:Key="MyDumbMockedList" Type="local:MockRecord">
                <local:MockRecord FirstName="Fred" LastName="Flintstone" Email="fred@noemail.org" />
                <local:MockRecord FirstName="Wilma" LastName="Flintstone" Email="wilma@noemail.org" />
                <local:MockRecord FirstName="Barney" LastName="Rubble" Email="barney@noemail.org" />
            </x:Array>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <DataGrid  Margin="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                   ItemsSource="{Binding Source={StaticResource MyDumbMockedList}}"/>
    </Grid>
    

    【讨论】:

    • 感谢您提出这个问题,Guish。我按照您的第一个示例进行操作,但出现此运行时错误:'System.Windows.Data 错误:50:XmlDataProvider 具有未明确设置其 XmlNamespace (xmlns="") 的内联 XML。然而,数据确实出现在网格中。但是,如果我删除命名空间,则数据不会插入到网格中,但不会收到错误消息。如果我输入“x”(不带引号),它也不起作用。我该如何解决这个难题?
    • 我稍微搜索了一下,找到了这个链接....不知道能不能帮到你:http://blog.wouldbetheologian.com/2009/07/why-wpf-databinding-is-awful-technology.html
    • 该链接中的示例还给出了错误 50。基于此 link 中的第一个示例,我尝试将 XmlNamespaceMappingCollection 添加到我的 Window.Resources 但我收到错误消息:类型确实不实现 IList:XmlNamespaceMappingCollection。所以我又卡住了。
    【解决方案2】:

    您可以在 XAML 中处理静态数据,是的,但是您需要为记录格式创建一个简单的类。例如,您可以创建这个类文件:

    namespace TestNamespace
    {
        public class MockRecord
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Email { get; set; }
        }
    }
    

    现在您可以在 XAML DataGrid 中执行此操作:

    <DataGrid xmlns:local="clr-namespace:TestNamespace">
    
        <DataGrid.Columns>
            <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
            <DataGridTextColumn Header="Rate" Binding="{Binding LastName}" />
            <DataGridTextColumn Header="Cost" Binding="{Binding Email}" />
        </DataGrid.Columns>
    
         <!-- Static Data which will automatically go in the datagrid -->
         <local:MockRecord FirstName="Fred" LastName="Flintstone" Email="fred@noemail.org" />
         <local:MockRecord FirstName="Wilma" LastName="Flintstone" Email="wilma@noemail.org" />
         <local:MockRecord FirstName="Barney" LastName="Rubble" Email="barney@noemail.org" />
    </DataGrid>
    

    【讨论】:

    • 除了我错过了 xmlns:local 的部分外,几乎有相同的解决方案。它在编译时有效,但我在 XAML 设计器中看不到它,即使 xmlns:local 定义存在于 DataGrid 所在的 UserControl 的定义中。非常感谢您的分享。
    【解决方案3】:

    查看此MSDN page 的示例部分

    由于datagrid使用了类似于Combobox或ListBox的ItemsControl,datagrid应该是相同的逻辑。在那个例子中,他们基本上是在纯 XAML 中创建一个完整的对象集合。

    <XmlDataProvider x:Key="Employees" XPath="/Employees/*">
      <x:XData>
        <Employees xmlns="">
          <Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
          <Employee Name="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
          <Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
          <Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
          <Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
        </Employees>
      </x:XData>
    </XmlDataProvider>
    
    <DataTemplate x:Key="EmployeeItemTemplate">
      <TextBlock Text="{Binding XPath=@Name}" />
    </DataTemplate>
    
    
    ...
    
    <ListBox Name="employeeListBox"
             ItemsSource="{Binding Source={StaticResource Employees}}"
             ItemTemplate="{StaticResource EmployeeItemTemplate}"
             SelectedValue="12345"
             SelectedValuePath="@EmployeeNumber"/>
    
    <TextBlock Text="{Binding ElementName=employeeListBox, 
                      Path=SelectedValue}"/>
    

    【讨论】:

    • 为什么要投反对票?人们,如果您对答案投反对票,您需要至少对“为什么”添加评论
    • 不,它不仅仅是链接。如果我只是在第一行之后停下来,那么它就会有!我实际上解释了为什么链接文章中的示例实际上会对 OP 有所帮助。因此它被标记为“接受的答案”。但无论如何。!
    • 您链接的页面上的示例部分似乎是空的
    • 这是 6 年的问题,MSDN 链接指向最新版本,我现在在这里粘贴了实际示例。
    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多