Help: Need to cause DataGrid row to "flush" contents

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Junkguy

    Help: Need to cause DataGrid row to "flush" contents


    I need some help programmaticall y causing a row in a DataGrid to "flush"
    its contents to its bound data (in Visual Studio 6 using Windows Forms
    with C#).

    My issue is I want to send an update to a database from a menu command
    while the user is editing a DataGrid. This is unusual in regard to
    examples and normal practice in that the cell of the DataGrid still has
    the focus. In all examples I can find, the user normally presses a
    button on a Form. This practice causes the DataGrid to lose focus and
    automatically flush the current row's contents to its bound data member.
    But when I attempt to perform an update while the user is STILL editing
    data in a row, the DataSet updates WITHOUT that particular row.

    I attempted to circumvent this problem by simply setting the focus of
    another control on the form (e.g. btnSave.Focus() ), hoping that the
    DataGrid would lose focus and flush its row contents to the DataSet, but
    this proved to be inexplicably ineffective. The row was still not
    flushed. I don't know if a Focus() call needs to iterate once through
    the event chain before it finalizes or what.

    I really want to do this the right way. I don't want to use a hack like
    selecting another row before updating, but I can't find any method in
    DataGrid that will force its contents to flush to its bound data. Does
    anyone have the definitive procedure on this. Perhaps I'm simply missing
    an obvious or well known method here?
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: Need to cause DataGrid row to "flush&quo t; contents

    Junkguy,

    I think that the best way to do this would be to call the EndEdit method
    on the data grid before you perform the action. This will allow you to end
    the current edit and should update the underlying data source when done.

    Hope this helps.


    --
    - Nicholas Paldino [.NET/C# MVP]
    - nick(dot)paldin o=at=exisconsul ting<dot>com

    "Junkguy" <junkguy@columb us.rr.com> wrote in message
    news:junkguy-722928.10580729 092003@news-server-fe-01.columbus.rr. com...[color=blue]
    >
    > I need some help programmaticall y causing a row in a DataGrid to "flush"
    > its contents to its bound data (in Visual Studio 6 using Windows Forms
    > with C#).
    >
    > My issue is I want to send an update to a database from a menu command
    > while the user is editing a DataGrid. This is unusual in regard to
    > examples and normal practice in that the cell of the DataGrid still has
    > the focus. In all examples I can find, the user normally presses a
    > button on a Form. This practice causes the DataGrid to lose focus and
    > automatically flush the current row's contents to its bound data member.
    > But when I attempt to perform an update while the user is STILL editing
    > data in a row, the DataSet updates WITHOUT that particular row.
    >
    > I attempted to circumvent this problem by simply setting the focus of
    > another control on the form (e.g. btnSave.Focus() ), hoping that the
    > DataGrid would lose focus and flush its row contents to the DataSet, but
    > this proved to be inexplicably ineffective. The row was still not
    > flushed. I don't know if a Focus() call needs to iterate once through
    > the event chain before it finalizes or what.
    >
    > I really want to do this the right way. I don't want to use a hack like
    > selecting another row before updating, but I can't find any method in
    > DataGrid that will force its contents to flush to its bound data. Does
    > anyone have the definitive procedure on this. Perhaps I'm simply missing
    > an obvious or well known method here?[/color]


    Comment

    • Erald Kulk

      #3
      Re: Help: Need to cause DataGrid row to &quot;flush&quo t; contents

      junkguy, what I do is the following:

      this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);
      this.grdWorkshe et.CurrentCell = new DataGridCell(0, 1);
      this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);

      this way, the focus changes to an existing cell in the datagrid. and
      even if the new edited cell is in the same row, the changes will be
      updated.

      Erald Kulk

      Comment

      • Junkguy

        #4
        Re: Need to cause DataGrid row to &quot;flush&quo t; contents

        In article <Og54b0rhDHA.27 48@TK2MSFTNGP11 .phx.gbl>,
        "Nicholas Paldino [.NET/C# MVP]" <nicholas.paldi no@exisconsulti ng.com>
        wrote:
        [color=blue]
        > I think that the best way to do this would be to call the EndEdit method
        > on the data grid before you perform the action. This will allow you to end
        > the current edit and should update the underlying data source when done.
        >
        > Hope this helps.[/color]


        Thanks Nicholas,

        Wish it would help, but apparently EndEdit is already being called when
        AcceptChanges() is called on the data table. I literally tried getting
        the CurrencyManager and calling its EndCurrentEdit( ) call. It still
        refused to work. As usual, there is some esoteric thing that happens to
        really really make the thing end and nobody has caught the bug because
        the whateveritiscal l is getting coincidentally invoked by leaving the
        DataGrid.

        --Junkguy

        --
        Junkguy

        Comment

        • Junkguy

          #5
          Re: Help: Need to cause DataGrid row to &quot;flush&quo t; contents

          In article <d984f6c9.03093 00206.41f8f2c@p osting.google.c om>,
          erald@delta-travel.nl (Erald Kulk) wrote:
          [color=blue]
          > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);
          > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 1);
          > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);
          >
          > this way, the focus changes to an existing cell in the datagrid. and
          > even if the new edited cell is in the same row, the changes will be
          > updated.[/color]

          Yeah, that's cool.

          I had tried

          dg.CurrentCell = new DataGridCell(dg .CurrentRowInde x + 1,0);

          This makes it go one row down, which I think is safer because if your
          datagrid only contains one column, selecting the second cell won't work-
          and in a datagrid that allows edits, there is always "one more row" on
          the end. Or if you are on that end row, it does not affect it.

          I tried earlier

          dg.CurrentRowIn dex += 1;

          But that didn't work for some reason, and it throws an exception if you
          are on the end row.

          The only issue I have found with the "new cell" idea is when the row you
          are currently on has a Validation error, the cell you were editing does
          not re-highlight. It does re-hilight when you use the mouse to go to the
          next row. Weird.

          I really want to find out what the exact procedure is. I have actually
          been stepping through the disassembled Microsoft code to see what the
          heck they are doing. But that is pretty tedious and difficult and I
          still haven't figured it out.

          <rant>You know, EVERY other window toolkit I have ever used gives you
          the code- which of course makes it easy to figure out what they are
          doing. Microsoft hides it. I can see hiding the underlying operating
          system but come on! The docs are so poor and they use so many esoteric
          methodologies it just makes my job that much harder.</rant>

          Until I figure out the correct procedures, I guess I'll use the "new
          cell" method you describe.

          Thanks for your advice.

          --
          Junkguy

          Comment

          • Dmitriy Lapshin [C# / .NET MVP]

            #6
            Re: Help: Need to cause DataGrid row to &quot;flush&quo t; contents

            Hi,
            [color=blue]
            > dg.CurrentCell = new DataGridCell(dg .CurrentRowInde x + 1,0);[/color]

            I'd suggest

            dg.CurrentCell = new DataGridCell(dg .CurrentCell.Ro wNumber + 1,0);

            because CurrentRowIndex is hardwired to the parent table and this approach
            won't work for a child table if you bind the grid to a master-detail
            dataset.

            Unfortunately I cannot access the message that started the thread, could you
            please re-post your original problem and I could then probably suggest
            something?

            --
            Dmitriy Lapshin [C# / .NET MVP]
            X-Unity Test Studio

            Bring the power of unit testing to VS .NET IDE

            "Junkguy" <junkguy@columb us.rr.com> wrote in message
            news:junkguy-FDF73D.11204130 092003@news-server-fe-01.columbus.rr. com...[color=blue]
            > In article <d984f6c9.03093 00206.41f8f2c@p osting.google.c om>,
            > erald@delta-travel.nl (Erald Kulk) wrote:
            >[color=green]
            > > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);
            > > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 1);
            > > this.grdWorkshe et.CurrentCell = new DataGridCell(0, 0);
            > >
            > > this way, the focus changes to an existing cell in the datagrid. and
            > > even if the new edited cell is in the same row, the changes will be
            > > updated.[/color]
            >
            > Yeah, that's cool.
            >
            > I had tried
            >
            > dg.CurrentCell = new DataGridCell(dg .CurrentRowInde x + 1,0);
            >
            > This makes it go one row down, which I think is safer because if your
            > datagrid only contains one column, selecting the second cell won't work-
            > and in a datagrid that allows edits, there is always "one more row" on
            > the end. Or if you are on that end row, it does not affect it.
            >
            > I tried earlier
            >
            > dg.CurrentRowIn dex += 1;
            >
            > But that didn't work for some reason, and it throws an exception if you
            > are on the end row.
            >
            > The only issue I have found with the "new cell" idea is when the row you
            > are currently on has a Validation error, the cell you were editing does
            > not re-highlight. It does re-hilight when you use the mouse to go to the
            > next row. Weird.
            >
            > I really want to find out what the exact procedure is. I have actually
            > been stepping through the disassembled Microsoft code to see what the
            > heck they are doing. But that is pretty tedious and difficult and I
            > still haven't figured it out.
            >
            > <rant>You know, EVERY other window toolkit I have ever used gives you
            > the code- which of course makes it easy to figure out what they are
            > doing. Microsoft hides it. I can see hiding the underlying operating
            > system but come on! The docs are so poor and they use so many esoteric
            > methodologies it just makes my job that much harder.</rant>
            >
            > Until I figure out the correct procedures, I guess I'll use the "new
            > cell" method you describe.
            >
            > Thanks for your advice.
            >
            > --
            > Junkguy[/color]

            Comment

            • Dmitriy Lapshin [C# / .NET MVP]

              #7
              Re: Need to cause DataGrid row to &quot;flush&quo t; contents

              Hi,

              The CurrencyManager .EndCurrentEdit followed by DataGrid.EndEdi t sequence
              works just fine for me. Note that it is a two-step sequence and any of the
              steps alone won't do the job. If you follow this sequence and it doesn't
              work, could you post a code snippet?

              --
              Dmitriy Lapshin [C# / .NET MVP]
              X-Unity Test Studio

              Bring the power of unit testing to VS .NET IDE

              "Junkguy" <junkguy@columb us.rr.com> wrote in message
              news:junkguy-E18679.09223930 092003@news-server-fe-01.columbus.rr. com...[color=blue]
              > In article <Og54b0rhDHA.27 48@TK2MSFTNGP11 .phx.gbl>,
              > "Nicholas Paldino [.NET/C# MVP]" <nicholas.paldi no@exisconsulti ng.com>
              > wrote:
              >[color=green]
              > > I think that the best way to do this would be to call the EndEdit[/color][/color]
              method[color=blue][color=green]
              > > on the data grid before you perform the action. This will allow you to[/color][/color]
              end[color=blue][color=green]
              > > the current edit and should update the underlying data source when done.
              > >
              > > Hope this helps.[/color]
              >
              >
              > Thanks Nicholas,
              >
              > Wish it would help, but apparently EndEdit is already being called when
              > AcceptChanges() is called on the data table. I literally tried getting
              > the CurrencyManager and calling its EndCurrentEdit( ) call. It still
              > refused to work. As usual, there is some esoteric thing that happens to
              > really really make the thing end and nobody has caught the bug because
              > the whateveritiscal l is getting coincidentally invoked by leaving the
              > DataGrid.
              >
              > --Junkguy
              >
              > --
              > Junkguy[/color]

              Comment

              • Junkguy

                #8
                Re: Need to cause DataGrid row to &quot;flush&quo t; contents

                In article <eOsTjxAiDHA.14 80@TK2MSFTNGP12 .phx.gbl>,
                "Dmitriy Lapshin [C# / .NET MVP]" <x-code@no-spam-please.hotpop.c om> wrote:
                [color=blue]
                > The CurrencyManager .EndCurrentEdit followed by DataGrid.EndEdi t sequence
                > works just fine for me.[/color]

                Thanks,

                The thing that concerned me about this was that somebody else might attempt to
                call DataGrid.EndEdi t() because it was automatically invoked (i.e. I didn't
                call BeginEdit). DataGrid.EndEdi t() needs a DataGridColumnS tyle, row number,
                and a boolean. Who the heck is holding this information while I'm editing a
                cell? I would like to get them to do the work. Barring that, I'm a little
                unsure as to the best way to get the current DataGridColumnS tyle as DataGrid
                does not seem to provide an easy means to it. How do you do get it securely
                and then insure that nobody else will make the EndEdit call?

                P.S. Here is the original posting I made as per your request:
                [color=blue]
                > I need some help programmaticall y causing a row in a DataGrid to "flush"
                > its contents to its bound data (in Visual Studio 6 using Windows Forms
                > with C#).
                >
                > My issue is I want to send an update to a database from a menu command
                > while the user is editing a DataGrid. This is unusual in regard to
                > examples and normal practice in that the cell of the DataGrid still has
                > the focus. In all examples I can find, the user normally presses a
                > button on a Form. This practice causes the DataGrid to lose focus and
                > automatically flush the current row's contents to its bound data member.
                > But when I attempt to perform an update while the user is STILL editing
                > data in a row, the DataSet updates WITHOUT that particular row.
                >
                > I attempted to circumvent this problem by simply setting the focus of
                > another control on the form (e.g. btnSave.Focus() ), hoping that the
                > DataGrid would lose focus and flush its row contents to the DataSet, but
                > this proved to be inexplicably ineffective. The row was still not
                > flushed. I don't know if a Focus() call needs to iterate once through
                > the event chain before it finalizes or what.
                >
                > I really want to do this the right way. I don't want to use a hack like
                > selecting another row before updating, but I can't find any method in
                > DataGrid that will force its contents to flush to its bound data. Does
                > anyone have the definitive procedure on this. Perhaps I'm simply missing
                > an obvious or well known method here?[/color]

                --
                Junkguy

                Comment

                • Dmitriy Lapshin [C# / .NET MVP]

                  #9
                  Re: Need to cause DataGrid row to &quot;flush&quo t; contents

                  > The thing that concerned me about this was that somebody else might
                  attempt to[color=blue]
                  > call DataGrid.EndEdi t() because it was automatically invoked (i.e. I[/color]
                  didn't[color=blue]
                  > call BeginEdit).[/color]

                  No problem with that. To the best of my knowledge, no exception will be
                  thrown and no bad thing will happen. The method will just return false.
                  [color=blue]
                  > DataGrid.EndEdi t() needs a DataGridColumnS tyle, row number, and a boolean.
                  > Who the heck is holding this information while I'm editing a cell?[/color]

                  The row number can be obtained from dataGrid.Curren tCell.RowNumber .
                  The boolean just means whether you want to commit changes or roll them back.
                  The column style is the hardest thing. The only way I know is having column
                  styles created manually through the TableStyles/GridColumnStyle s collection
                  designers and then obtaining the corresponding instance by the column
                  number. The column number is also determined frin the CurrentCell property.

                  P.S. I am currently finishing work on a DataGrid article that should cover
                  this issue in particular.

                  --
                  Dmitriy Lapshin [C# / .NET MVP]
                  X-Unity Test Studio

                  Bring the power of unit testing to VS .NET IDE

                  "Junkguy" <junkguy@columb us.rr.com> wrote in message
                  news:junkguy-4AC0A7.20415701 102003@news-server-fe-02.columbus.rr. com...[color=blue]
                  > In article <eOsTjxAiDHA.14 80@TK2MSFTNGP12 .phx.gbl>,
                  > "Dmitriy Lapshin [C# / .NET MVP]" <x-code@no-spam-please.hotpop.c om>[/color]
                  wrote:[color=blue]
                  >[color=green]
                  > > The CurrencyManager .EndCurrentEdit followed by DataGrid.EndEdi t sequence
                  > > works just fine for me.[/color]
                  >
                  > Thanks,
                  >
                  > The thing that concerned me about this was that somebody else might[/color]
                  attempt to[color=blue]
                  > call DataGrid.EndEdi t() because it was automatically invoked (i.e. I[/color]
                  didn't[color=blue]
                  > call BeginEdit). DataGrid.EndEdi t() needs a DataGridColumnS tyle, row[/color]
                  number,[color=blue]
                  > and a boolean. Who the heck is holding this information while I'm editing[/color]
                  a[color=blue]
                  > cell? I would like to get them to do the work. Barring that, I'm a little
                  > unsure as to the best way to get the current DataGridColumnS tyle as[/color]
                  DataGrid[color=blue]
                  > does not seem to provide an easy means to it. How do you do get it[/color]
                  securely[color=blue]
                  > and then insure that nobody else will make the EndEdit call?
                  >
                  > P.S. Here is the original posting I made as per your request:
                  >[color=green]
                  > > I need some help programmaticall y causing a row in a DataGrid to "flush"
                  > > its contents to its bound data (in Visual Studio 6 using Windows Forms
                  > > with C#).
                  > >
                  > > My issue is I want to send an update to a database from a menu command
                  > > while the user is editing a DataGrid. This is unusual in regard to
                  > > examples and normal practice in that the cell of the DataGrid still has
                  > > the focus. In all examples I can find, the user normally presses a
                  > > button on a Form. This practice causes the DataGrid to lose focus and
                  > > automatically flush the current row's contents to its bound data member.
                  > > But when I attempt to perform an update while the user is STILL editing
                  > > data in a row, the DataSet updates WITHOUT that particular row.
                  > >
                  > > I attempted to circumvent this problem by simply setting the focus of
                  > > another control on the form (e.g. btnSave.Focus() ), hoping that the
                  > > DataGrid would lose focus and flush its row contents to the DataSet, but
                  > > this proved to be inexplicably ineffective. The row was still not
                  > > flushed. I don't know if a Focus() call needs to iterate once through
                  > > the event chain before it finalizes or what.
                  > >
                  > > I really want to do this the right way. I don't want to use a hack like
                  > > selecting another row before updating, but I can't find any method in
                  > > DataGrid that will force its contents to flush to its bound data. Does
                  > > anyone have the definitive procedure on this. Perhaps I'm simply missing
                  > > an obvious or well known method here?[/color]
                  >
                  > --
                  > Junkguy[/color]

                  Comment

                  • Junkguy

                    #10
                    Re: Need to cause DataGrid row to &quot;flush&quo t; contents

                    In article <u1WozkMiDHA.16 80@TK2MSFTNGP12 .phx.gbl>,
                    "Dmitriy Lapshin [C# / .NET MVP]" <x-code@no-spam-please.hotpop.c om> wrote:
                    [color=blue][color=green]
                    > > DataGrid.EndEdi t() needs a DataGridColumnS tyle, row number, and a boolean.
                    > > Who the heck is holding this information while I'm editing a cell?[/color]
                    >[/color]

                    Thanks Dmitriy for you response.

                    We still do not know what called BeginEdit. Some object, somewhere made the
                    initial call and still holds the info. I think I might just step through the
                    assembly code and find out.
                    [color=blue]
                    > The row number can be obtained from dataGrid.Curren tCell.RowNumber .
                    > The boolean just means whether you want to commit changes or roll them back.
                    > The column style is the hardest thing. The only way I know is having column
                    > styles created manually through the TableStyles/GridColumnStyle s collection
                    > designers and then obtaining the corresponding instance by the column
                    > number.[/color]

                    Well there's the rub isn't it. Getting the current column style is the most
                    mind-numbingly difficult thing and it should not be. Committing a row to the
                    data member should not be like pulling teeth. It should be a common
                    programmer-accessible call without having to go through hoops.


                    Anyway, thanks again. I look forward to reading your article.

                    --
                    Junkguy

                    Comment

                    • Dmitriy Lapshin [C# / .NET MVP]

                      #11
                      Re: Need to cause DataGrid row to &quot;flush&quo t; contents

                      Junkguy,
                      [color=blue]
                      > We still do not know what called BeginEdit. Some object, somewhere made[/color]
                      the[color=blue]
                      > initial call and still holds the info. I think I might just step through[/color]
                      the[color=blue]
                      > assembly code and find out.[/color]

                      I wonder why would you need to find out this information? In my exerience, I
                      was always happily calling EndEdit without caring who had called BeginEdit.
                      When you know the row and the column, that's all you need to force the grid
                      commit editing.
                      [color=blue]
                      > Well there's the rub isn't it. Getting the current column style is the[/color]
                      most[color=blue]
                      > mind-numbingly difficult thing and it should not be. Committing a row to[/color]
                      the[color=blue]
                      > data member should not be like pulling teeth. It should be a common
                      > programmer-accessible call without having to go through hoops.[/color]

                      Wholeheartedly agree with this. The DataGrid is full of secrets and
                      surprises, like a good computer game should be :-))

                      --
                      Dmitriy Lapshin [C# / .NET MVP]
                      X-Unity Test Studio

                      Bring the power of unit testing to VS .NET IDE

                      "Junkguy" <junkguy@columb us.rr.com> wrote in message
                      news:junkguy-6BA225.12003502 102003@news-server-fe-01.columbus.rr. com...[color=blue]
                      > In article <u1WozkMiDHA.16 80@TK2MSFTNGP12 .phx.gbl>,
                      > "Dmitriy Lapshin [C# / .NET MVP]" <x-code@no-spam-please.hotpop.c om>[/color]
                      wrote:[color=blue]
                      >[color=green][color=darkred]
                      > > > DataGrid.EndEdi t() needs a DataGridColumnS tyle, row number, and a[/color][/color][/color]
                      boolean.[color=blue][color=green][color=darkred]
                      > > > Who the heck is holding this information while I'm editing a cell?[/color]
                      > >[/color]
                      >
                      > Thanks Dmitriy for you response.
                      >
                      > We still do not know what called BeginEdit. Some object, somewhere made[/color]
                      the[color=blue]
                      > initial call and still holds the info. I think I might just step through[/color]
                      the[color=blue]
                      > assembly code and find out.
                      >[color=green]
                      > > The row number can be obtained from dataGrid.Curren tCell.RowNumber .
                      > > The boolean just means whether you want to commit changes or roll them[/color][/color]
                      back.[color=blue][color=green]
                      > > The column style is the hardest thing. The only way I know is having[/color][/color]
                      column[color=blue][color=green]
                      > > styles created manually through the TableStyles/GridColumnStyle s[/color][/color]
                      collection[color=blue][color=green]
                      > > designers and then obtaining the corresponding instance by the column
                      > > number.[/color]
                      >
                      > Well there's the rub isn't it. Getting the current column style is the[/color]
                      most[color=blue]
                      > mind-numbingly difficult thing and it should not be. Committing a row to[/color]
                      the[color=blue]
                      > data member should not be like pulling teeth. It should be a common
                      > programmer-accessible call without having to go through hoops.
                      >
                      >
                      > Anyway, thanks again. I look forward to reading your article.
                      >
                      > --
                      > Junkguy[/color]

                      Comment

                      • Junkguy

                        #12
                        Re: Need to cause DataGrid row to &quot;flush&quo t; contents

                        In article <OaClpjXiDHA.40 12@tk2msftngp13 .phx.gbl>,
                        "Dmitriy Lapshin [C# / .NET MVP]" <x-code@no-spam-please.hotpop.c om> wrote:
                        [color=blue]
                        > I wonder why would you need to find out this information? In my exerience, I
                        > was always happily calling EndEdit without caring who had called BeginEdit.
                        > When you know the row and the column, that's all you need to force the grid
                        > commit editing.[/color]

                        Just because it would perform all the nessesary steps to clean up after
                        itself. It may well be that nobody holds the info, and when you leave a cell
                        (for example) some generic code just finds the current column style and calls
                        EndEdit itself. If EndEdit is truly all that needs called then your suggestion
                        is fine.

                        I was simply concerned that perhaps some call X other than EndEdit was being
                        called first (i.e. EndEdit is called inside X) and X would have some cleanup
                        code inside it that should be done (like maybe textbox validation or a
                        delegate call). If we call EndEdit ourselves and skip this cleanup in call X,
                        we may well skip some important code, or worse, it may break sometime in the
                        future when Microsoft ammends call X.

                        But I'm probably just being paranoid. Thanks for your help.

                        --
                        Junkguy

                        Comment

                        Working...