Silverlight DataGrid.BeginEdit () не переводит ячейку в режим редактирования

У меня есть требование, когда я хочу добавить новую пустую строку, которую я заполнил в строке в сетке, и она также должна быть в режиме редактирования, когда я могу начать вводить текст сразу после перехода к ячейке за вкладкой.

Для этого я попытался использовать функцию BeginEdit таблицы данных, но, похоже, она вообще не работает.

Вот мой код: 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"
               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());
            }
        }
    }
}

Это тестовое приложение создано с использованием шаблона проекта MVVM Lighttoolkit. Пожалуйста, дайте мне знать, если вам понадобится дополнительная информация.

Ура --- Jag


person Jag    schedule 17.12.2010    source источник
comment
Спасибо дециклону. Я изо всех сил пытался правильно отформатировать :-)   -  person Jag    schedule 20.12.2010


Ответы (2)


Я боролся с той же проблемой, я обнаружил, что помимо вызова BeginEdit() вам необходимо обработать событие PreparingCellForEdit(), чтобы установить фокус на TextBox:

private void dgTest_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
    TextBox tb = e.EditingElement as TextBox;
    if (tb != null)
    {
        tb.Focus();
    }
}

Я нашел это решение здесь: http://forums.silverlight.net/t/152064.aspx

person Ben    schedule 11.09.2012
comment
Хороший улов! Спасибо! Я просто хочу добавить это на тот случай, если у Cell есть другой элемент управления, то есть AutocompleteBox или любой другой элемент, который мы должны передать этому классу. - person DmitryBoyko; 16.04.2014

Этот обходной путь устранил проблему для меня. Вместо прямого вызова BeginEdit() он использует диспетчер для его вызова.

var action = new Action(() =>
{
    dataGrid.BeginEdit();
});
this.Dispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.ApplicationIdle, null);

Этот ответ был найден здесь: https://xceed.com/forums/topic/BeginEdit-function-just-focus-the-selected-cell/

person Ben Spessler    schedule 29.09.2017