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 ?
集合项转到 DataGrid 行的数据上下文。
UI 元素无法编辑其 DataContext。
因此,对于字符串,您需要使用所需类型的 属性 创建一个引用 ty 并编辑此 属性。
而且这个类型必须有一个默认的构造函数。
由于列表可以在多个绑定中使用,所以列表的类型应该不是简单的集合,而是可观察的集合。
所用示例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 中引用它们通常是非常糟糕的代码。
我在 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 ?
集合项转到 DataGrid 行的数据上下文。 UI 元素无法编辑其 DataContext。 因此,对于字符串,您需要使用所需类型的 属性 创建一个引用 ty 并编辑此 属性。 而且这个类型必须有一个默认的构造函数。
由于列表可以在多个绑定中使用,所以列表的类型应该不是简单的集合,而是可观察的集合。
所用示例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 中引用它们通常是非常糟糕的代码。