Silverlight DataGrid.BeginEdit() doesn't put the cell in edit mode
I have a requirement where I want to add a new blank row I have filled in a row in the grid and it also needs to be in edit mode where I can start typing straight away after reaching on the cell by tab.
For this I tried to use the BeginEdit function of the datagrid but it doesn't seem to work at all.
Here is my code: MainPage.xaml
<UserControl x:Class="DataGridTest.MainPage"
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"
mc:Ignorable="d"
Height="192"
Width="356"
DataContext="{Binding Main, Source={StaticResource Locator}}" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
开发者_Python百科 FontWeight="Bold"
Foreground="Purple"
Text="{Binding Welcome}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<sdk:DataGrid AutoGenerateColumns="True" Height="100" HorizontalAlignment="Left" Margin="12,51,0,0" Name="dgTest" VerticalAlignment="Top" Width="332" ItemsSource="{Binding DataGridItems,Mode=TwoWay}" />
</Grid>
MainPage.xaml.cs
using System.Windows.Controls;
using DataGridTest.ViewModel;
using GalaSoft.MvvmLight.Messaging;
namespace DataGridTest
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Messenger.Default.Register<bool>(this, MakeDataGridEditable);
}
public void MakeDataGridEditable(bool flag)
{
if (flag)
{
dgTest.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateSource();
MainViewModel dataContext = DataContext as MainViewModel;
dgTest.SelectedIndex = dataContext.DataGridItems.Count - 1;
dgTest.CurrentColumn = dgTest.Columns[0];
dgTest.UpdateLayout();
dgTest.Focus();
dgTest.BeginEdit();
}
}
}
}
MainViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
namespace DataGridTest.ViewModel
{
public class MainViewModel : ViewModelBase
{
DataGridItem dataGridItem;
private ObservableCollection<DataGridItem> dataGridItems;
public ObservableCollection<DataGridItem> DataGridItems
{
get
{
return dataGridItems;
}
set
{
dataGridItems = value;
RaisePropertyChanged("DataGridItems");
}
}
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs "for real"
dataGridItems = new ObservableCollection<DataGridItem>();
dataGridItem = new DataGridItem();
dataGridItems.Add(dataGridItem);
dataGridItem.ChangesCommitted += new EventHandler<EventArgs>(dataGridItem_ChangesCommitted);
}
}
void dataGridItem_ChangesCommitted(object sender, EventArgs e)
{
dataGridItem.ChangesCommitted -= new EventHandler<EventArgs>(dataGridItem_ChangesCommitted);
CreateNewDataGridItem();
dataGridItem.ChangesCommitted += new EventHandler<EventArgs>(dataGridItem_ChangesCommitted);
Messenger.Default.Send<bool>(true);
}
private void CreateNewDataGridItem()
{
this.dataGridItem = new DataGridItem();
this.dataGridItems.Insert(dataGridItems.Count, dataGridItem);
}
}
public class DataGridItem : IEditableObject
{
public string ItemCode { get; set; }
public string ItemDescription { get; set; }
public void BeginEdit()
{
}
public void CancelEdit()
{
}
public event EventHandler<EventArgs> ChangesCommitted;
public void EndEdit()
{
if (null != ChangesCommitted)
{
EventArgs e = new EventArgs();
ChangesCommitted(this, new EventArgs());
}
}
}
}
This test app is done using MVVM Lighttoolkit project template. Please do let me know if you need any more info.
Cheers---Jag
I struggled with this same issue, I found that in addition to calling BeginEdit()
you need to handle the PreparingCellForEdit()
event to set focus on the TextBox
:
private void dgTest_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
TextBox tb = e.EditingElement as TextBox;
if (tb != null)
{
tb.Focus();
}
}
I found this solution here: http://forums.silverlight.net/t/152064.aspx
This workaround fixed the issue for me. Instead of calling BeginEdit()
directly, it uses the Dispatcher to invoke it.
var action = new Action(() =>
{
dataGrid.BeginEdit();
});
this.Dispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.ApplicationIdle, null);
This answer was found here: https://xceed.com/forums/topic/BeginEdit-function-just-focus-the-selected-cell/
精彩评论