WPF DataGrid: отсутствует пустая строка
Я создаю окно WPF с DataGrid
, и я хочу показать пустую строку "новый элемент" в нижней части сетки, которая позволяет мне добавить новый элемент в сетку. По какой-то причине пустая строка не отображается в сетке в моем окне. Вот разметка, которую я использовал для создания DataGrid
:
<toolkit:DataGrid x:Name="ProjectTasksDataGrid"
DockPanel.Dock="Top"
Style="{DynamicResource {x:Static res:SharedResources.FsBlueGridKey}}"
AutoGenerateColumns="False"
ItemsSource="{Binding SelectedProject.Tasks}"
RowHeaderWidth="0"
MouseMove="OnStartDrag"
DragEnter="OnCheckDropTarget"
DragOver="OnCheckDropTarget"
DragLeave="OnCheckDropTarget"
Drop="OnDrop"
InitializingNewItem="ProjectTasksDataGrid_InitializingNewItem">
<toolkit:DataGrid.Columns>
<toolkit:DataGridCheckBoxColumn HeaderTemplate="{DynamicResource {x:Static res:SharedResources.CheckmarkHeaderKey}}" Width="25" Binding="{Binding Completed}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Days" Width="75" Binding="{Binding NumDays}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Due Date" Width="75" Binding="{Binding DueDate, Converter={StaticResource standardDateConverter}}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Description" Width="*" Binding="{Binding Description}" IsReadOnly="false"/>
</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
Я не могу понять, почему пустая строка не отображается. Я пробовал очевидные вещи (IsReadOnly="false"
, CanUserAddRows="True"
), не повезло. Есть идеи, почему пустая строка отключена? Спасибо помощь.
7 ответов
Винсент Сибал опубликовал статья, описывающая, что требуется для добавления новых строк в DataGrid. Существует довольно много возможностей, и большинство из них зависит от типа коллекции, которую вы используете для SelectedProject.Tasks
.
Я бы рекомендовал убедиться, что" задачи " не являются коллекцией только для чтения и что она поддерживает один из необходимых интерфейсов (упомянутых в предыдущей ссылке), чтобы новые элементы могли быть добавлены правильно с DataGrid.
наконец-то вернулся к этому. Я не собираюсь менять принятый ответ (зеленая галочка), но вот причина проблемы:
моя модель представления обертывает классы домена для обеспечения инфраструктуры, необходимой WPF. Я написал статья CodeProject в методе wrap, который я использую, который включает класс коллекции, который имеет два параметра типа:
VmCollection<VM, DM>
здесь DM является обернутым классом домена, и DM это класс WPF, который обертывает его.
Это truns, что по какой-то странной причине, имея второй параметр типа класса коллекции вызывает в WPF DataGrid, чтобы стать недоступным. Исправление заключается в устранении параметра второго типа.
Не могу сказать, почему это работает, только то, что он делает. Надеюсь, это поможет кому-то еще.
на мой взгляд, это ошибка в DataGrid. ссылка Майка Блэндфорда помогло мне, наконец, понять, в чем проблема: DataGrid не распознает тип строк, пока он не будет связан с реальным объектом. Строка редактирования не отображается b / c сетка данных не знает типы столбцов. Можно подумать, что привязка строго типизированной коллекции будет работать, но это не.
чтобы расширить ответ Майка Блэндфорда, необходимо сначала назначить пустую коллекцию а затем добавьте и удалите строку. Например,
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// data binding
dataGridUsers.ItemsSource = GetMembershipUsers();
EntRefUserDataSet.EntRefUserDataTable dt = (EntRefUserDataSet.EntRefUserDataTable)dataGridUsers.ItemsSource;
// hack to force edit row to appear for empty collections
if (dt.Rows.Count == 0)
{
dt.AddEntRefUserRow("", "", false, false);
dt.Rows[0].Delete();
}
}
добавьте пустой элемент в ItemsSource, а затем удалите его. Возможно, вам придется установить CanUserAddRows обратно в true после этого. Я читал это решение здесь: (сообщения Джарри и Рика Роена)
У меня была эта проблема, когда я установил ItemsSource в DefaultView DataTable, и представление было пустым. Столбцы были определены, хотя, таким образом, он должен был их получить. Хех.
для меня лучший способ реализовать редактируемый асинхронный DataGrid
выглядит так:
Модель Вид:
public class UserTextMainViewModel : ViewModelBase
{
private bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
this._isBusy = value;
OnPropertyChanged();
}
}
private bool _isSearchActive;
private bool _isLoading;
private string _searchInput;
public string SearchInput
{
get { return _searchInput; }
set
{
_searchInput = value;
OnPropertyChanged();
_isSearchActive = !string.IsNullOrEmpty(value);
ApplySearch();
}
}
private ListCollectionView _translationsView;
public ListCollectionView TranslationsView
{
get
{
if (_translationsView == null)
{
OnRefreshRequired();
}
return _translationsView;
}
set
{
_translationsView = value;
OnPropertyChanged();
}
}
private void ApplySearch()
{
var view = TranslationsView;
if (view == null) return;
if (!_isSearchActive)
{
view.Filter = null;
}
else if (view.Filter == null)
{
view.Filter = FilterUserText;
}
else
{
view.Refresh();
}
}
private bool FilterUserText(object o)
{
if (!_isSearchActive) return true;
var item = (UserTextViewModel)o;
return item.Key.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase) ||
item.Value.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase);
}
private ICommand _clearSearchCommand;
public ICommand ClearSearchCommand
{
get
{
return _clearSearchCommand ??
(_clearSearchCommand =
new DelegateCommand((param) =>
{
this.SearchInput = string.Empty;
}, (p) => !string.IsNullOrEmpty(this.SearchInput)));
}
}
private async void OnRefreshRequired()
{
if (_isLoading) return;
_isLoading = true;
IsBusy = true;
try
{
var result = await LoadDefinitions();
TranslationsView = new ListCollectionView(result);
}
catch (Exception ex)
{
//ex.HandleError();//TODO: Needs to create properly error handling
}
_isLoading = false;
IsBusy = false;
}
private async Task<IList> LoadDefinitions()
{
var translatioViewModels = await Task.Run(() => TranslationRepository.Instance.AllTranslationsCache
.Select(model => new UserTextViewModel(model)).ToList());
return translatioViewModels;
}
}
XAML:
<UserControl x:Class="UCM.WFDesigner.Views.UserTextMainView"
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"
xmlns:model="clr-namespace:Cellebrite.Diagnostics.Model.Entities;assembly=Cellebrite.Diagnostics.Model"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:converters1="clr-namespace:UCM.Infra.Converters;assembly=UCM.Infra"
xmlns:core="clr-namespace:UCM.WFDesigner.Core"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<DockPanel>
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"
HorizontalAlignment="Left">
<DockPanel>
<TextBlock Text="Search:"
DockPanel.Dock="Left"
VerticalAlignment="Center"
FontWeight="Bold"
Margin="0,0,5,0" />
<Button Style="{StaticResource StyleButtonDeleteCommon}"
Height="20"
Width="20"
DockPanel.Dock="Right"
ToolTip="Clear Filter"
Command="{Binding ClearSearchCommand}" />
<TextBox Text="{Binding SearchInput, UpdateSourceTrigger=PropertyChanged}"
Width="500"
VerticalContentAlignment="Center"
Margin="0,0,2,0"
FontSize="13" />
</DockPanel>
</StackPanel>
<Grid>
<DataGrid ItemsSource="{Binding Path=TranslationsView}"
AutoGenerateColumns="False"
SelectionMode="Single"
CanUserAddRows="True">
<DataGrid.Columns>
<!-- your columns definition is here-->
</DataGrid.Columns>
</DataGrid>
<!-- your "busy indicator", that shows to user a message instead of stuck data grid-->
<Border Visibility="{Binding IsBusy,Converter={converters1:BooleanToSomethingConverter TrueValue='Visible', FalseValue='Collapsed'}}"
Background="#50000000">
<TextBlock Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="Loading. . ."
FontSize="16" />
</Border>
</Grid>
</DockPanel>
этот шаблон позволяет работать с сеткой данных довольно простым способом, и код очень прост. Не забудьте создать конструктор по умолчанию для класса, представляющего источник данных.
это случилось со мной, я забыл новый экземпляр, и это был кошмар для меня . как только я создал экземпляр коллекции в onviewloaded, он был решен.
`observablecollection<T> _newvariable = new observablecollection<T>();`
это решило мою проблему. надеюсь, это может помочь другим