WPF DataGrid 中的空行

Empty Rows in WPF DataGrid

我在 wpf UserControl 上有一个 DataGrid 和一个 ComboBox。

namespace ApSap
{ 
public partial class DocumentView : UserControl
{
    public Document document;
    public DocumentView(Document selectedDoc)
    {          
        document = selectedDoc;
        InitializeComponent();
        DocBrowser.Navigate(document.FilePath);
     
        // shows only empty rows
        SapGrid.ItemsSource = document.SapDocNumbers;   
        // shows list of values correctly       
        Combo.ItemsSource = document.SapDocNumbers;
       }
    }
}

组合框正确显示 public 属性“SapDocNumbers”(整数列表)的内容,

然而,数据网格仅显示空行,尽管它们的数量是正确的。

XAML如下:

<UserControl x:Class="ApSap.DocumentView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         HorizontalAlignment="Stretch"
         VerticalAlignment="Stretch"
        >
<Grid  VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    
    <StackPanel  Grid.Column="1" Grid.Row="1"> 
        <DataGrid  AutoGenerateColumns="True"  x:Name="SapGrid"   Margin="10,10,10,10" >    
    </DataGrid>
        <Button x:Name="CreateInvoice" Content="Create Invoice"  Margin="10,10,10,10"  />  
        <Button x:Name="Save" Content="Save and Exit"   Margin="10,10,10,10"  />
        <ComboBox x:Name="Combo" Margin="10,10,10,10" />
    </StackPanel>
    


</Grid>

我在 XAML 网格定义中是否遗漏了什么,这意味着组合可以正常工作,但数据网格不能?

这里要求的是class:

的定义
public class Document : INotifyPropertyChanged
{
    private int _docID; 

    private List<Int64> _sapDocNumbers;     

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    } 

    public int DocID
    {
        get { return _docID; }
        set
        {
            if (value != _docID)
            {
                _docID = value;
                NotifyPropertyChanged();  
            }
        }
    }  

    public List<Int64> SapDocNumbers
    {
        get { return _sapDocNumbers; }
        set
        {
            if (value != _sapDocNumbers)
            {
                _sapDocNumbers = value;
                NotifyPropertyChanged();
            }
        }
    }

谢谢

您问题的答案取决于 collection 项目类型的实施。
ComboBox默认使用ToString()来表示item
DataGrid 呈现元素的属性 - 每个 属性 都有一个单独的列。
如果元素类型没有属性,DataGrid 将不会创建列并且不会显示任何内容。

要获得更准确的答案,请显示 collection 的类型及其元素类型的实现。

完成与问题澄清相关的回答:
你想显示 ulong collection.
此类型没有属性,因此 DataGrid 中的自动生成列无法创建列。

为了完成您的任务,您需要:

    <DataGrid  AutoGenerateColumns="False"  x:Name="SapGrid"   Margin="10" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Mode=OneWay}" Header="Number"/>
        </DataGrid.Columns>
    </DataGrid>

one final question, How do i get a blank row on the DataGrid so the user can add their own SapDocNumbers to the list ?

  1. 集合项转到 DataGrid 行的数据上下文。 UI 元素无法编辑其 DataContext。 因此,对于字符串,您需要使用所需类型的 属性 创建一个引用 ty 并编辑此 属性。 而且这个类型必须有一个默认的构造函数。

  2. 由于列表可以在多个绑定中使用,所以列表的类型应该不是简单的集合,而是可观察的集合。

所用示例class

using Simplified;

namespace ApSap
{
    public class DocumentRow : BaseInpc
    {
        private long _sapDocNumber;

        public long SapDocNumber { get => _sapDocNumber; set => Set(ref _sapDocNumber, value); }

        public DocumentRow(long sapDocNumber) => SapDocNumber = sapDocNumber;

        public DocumentRow() { }
    }

}
using Simplified;
using System.Collections.ObjectModel;

namespace ApSap
{
    public class Document : BaseInpc
    {
        private int _docID;

        public int DocID { get => _docID; set => Set(ref _docID, value); }

        public ObservableCollection<DocumentRow> SapDocNumbers { get; }
            = new ObservableCollection<DocumentRow>();

        public Document()
        {
        }

        public Document(int docID, params long[] sapDocNumbers)
        {
            DocID = docID;
            foreach (var number in sapDocNumbers)

                SapDocNumbers.Add(new DocumentRow(number));
        }

        public static Document ExampleInstance { get; } = new Document(123, 4, 5, 6, 7, 8, 9, 0);
    }

}
<Window x:Class="ApSap.DocumentWindow"
        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:ApSap"
        mc:Ignorable="d"
        Title="DocumentWindow" Height="450" Width="800"
        DataContext="{x:Static local:Document.ExampleInstance}">

    <Grid  VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <StackPanel  Grid.Column="1" Grid.Row="1">
            <TextBlock Margin="10,10,10,0">
                <Run Text="DocID:"/>
                <Run Text="{Binding DocID}"/>
            </TextBlock>
            <DataGrid  AutoGenerateColumns="True"  Margin="10"
                       ItemsSource="{Binding SapDocNumbers}"/>
            <Button x:Name="CreateInvoice" Content="Create Invoice"  Margin="10"  />
            <Button x:Name="Save" Content="Save and Exit"   Margin="10"  />
            <ComboBox x:Name="Combo" Margin="10" />
        </StackPanel>

        <DataGrid Grid.Row="1" AutoGenerateColumns="True"  Margin="10"
                  ItemsSource="{Binding SapDocNumbers}" VerticalAlignment="Top"/>
    </Grid>
</Window>

P.S. 学习设置数据上下文和绑定到它。使用 UI 元素的名称,在 Sharp 中引用它们通常是非常糟糕的代码。