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

Имам изискване, при което искам да добавя нов празен ред, който съм попълнил в ред в мрежата, и той също трябва да е в режим на редактиране, където мога да започна да въвеждам веднага, след като стигна до клетката по раздел.

За това се опитах да използвам функцията BeginEdit на datagrid, но изглежда изобщо не работи.

Ето моят код: 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(), той използва Dispatcher, за да го извика.

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