views:

3529

answers:

1

Take note of the code for this small WPF C# program made with Microsoft Visual Studio 2008:

.xaml

<Window x:Class="WpfDatagridTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfToolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <WpfToolkit:DataGrid 
        x:Name="DataGrid_" ItemsSource="{Binding}"
        SelectionMode="Extended"
        CanUserAddRows="False" CanUserDeleteRows="False"
        CanUserResizeRows="False" CanUserSortColumns="False"
     AutoGenerateColumns="False"
        RowHeaderWidth="17" RowHeight="25" />
    </Grid>
</Window>

.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Windows.Controls;

namespace WpfDatagridTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            const int MAX = 10;

            for(int i = 0; i < MAX; ++i)
                DataGrid_.Columns.Add(new DataGridTextColumn()
                {
                    Header = i
                });
            DataGrid_.Items.Add("");
        }
    }
}


This program simply shows a WPF toolkit datagrid with 10 columns with headers and an empty row.

There is problem that occurs when a certain cell of the empty row is selected and then clicked to be edited: the program crashes. A message box shows up in Visual Studio saying this: "There is no source code available for the current location." I would like to know how can I make a cell from a datagrid be editable?


Here is the exception and stacktrace:

System.InvalidOperationException was unhandled Message="'EditItem' is not allowed for this view."
Source="PresentationFramework"
StackTrace: at System.Windows.Controls.ItemCollection.System.ComponentModel.IEditableCollectionView.EditItem(Object item) at Microsoft.Windows.Controls.DataGrid.EditRowItem(Object rowItem) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGrid.cs:line 3396 at Microsoft.Windows.Controls.DataGrid.OnExecutedBeginEdit(ExecutedRoutedEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGrid.cs:line 2208 at Microsoft.Windows.Controls.DataGrid.OnExecutedBeginEdit(Object sender, ExecutedRoutedEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGrid.cs:line 2036 at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding) at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated) at System.Windows.Input.RoutedCommand.Execute(Object parameter, IInputElement target) at Microsoft.Windows.Controls.DataGrid.BeginEdit(RoutedEventArgs editingEventArgs) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGrid.cs:line 3059 at Microsoft.Windows.Controls.DataGridCell.OnAnyMouseLeftButtonDown(MouseButtonEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGridCell.cs:line 748 at Microsoft.Windows.Controls.DataGridCell.OnAnyMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataGrid\Microsoft\Windows\Controls\DataGridCell.cs:line 726 at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.UIElement.CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e) at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter) at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at WpfDatagridTest.App.Main() in C:\Users\Frank\Documents\Visual_Studio_2008\Projects\WpfDatagridTest\WpfDatagridTest\obj\Debug\App.g.cs:line 0 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:

+2  A: 

You are setting your ItemsSource to Binding, but there is no DataContext so this binding is useless. Then you are generating the columns in the code-behind and filling them with temporary data. From what I understand about the DataGrid, editing is only supported if there is data that the grid is bound to. Otherwise, what data are you editing?

Furthermore, I believe there is a IsReadOnly property (check the DataGrid documentation), which needs to be set to false (but I think it is false by default).

Charlie
I'm generating empty columns and giving those columns a header. The data I am editing is the empty cells.
Partial
Is it possible to bind the datagrid to a some sort of empty list that while you edit the datagrid cells it adds the text from that cell to the list?
Partial
Definitely. Create a new class that represents the data you are storing the datagrid. Then you could bind to an ObservableCollection of that data. Similar to this:http://msdn.microsoft.com/en-us/library/ms748365.aspx
Charlie
I've tried using the ItemsSource and an ArrayList. Is that a bad idea?
Partial
ArrayList will not provide automatic change notification like ObservableCollection. If you do not need any change notification then ArrayList should be ok. You could also implement INotifyPropertyChanged on your own ArrayList class.
Charlie