GotSharp? is a weblog from developers, for developers!

FoxPro, Memo fields and updating them

When you are (still) using ODBC or ADODB to update memo fields in a FoxPro table, you might run into the problem that all of your rows are updated instead of just the one when using AppendChunk.  This is probably caused by the fact that memo’s are stored in a separate FPT file, organized in blocks (or chunks, if you will) of text.  The memo field in the table holds a pointer to the first block in the FPT file.

The FoxPro ODBC driver seems to have problems setting the pointer when you set the memo of a row using a RecordSet.  If there are other rows after the current one with empty memo fields, the driver sets the pointer in those rows as well. Examine the following code:

rs.Open ...
While Len(sMemoData) > 254
    rs.Fields("Memo").AppendChunk Left(sMemoData, 254)
    sMemoData = Right(sMemoData, Len(sMemoData) - 254)
Wend

If Len(sMemoData) > 0 Then rs.Fields("Memo").AppendChunk sMemoData
rs.Update 

To avoid this from happening, you can use a ADO Command object and use parameters instead.  Make sure you set the correct size in the parameter!

cmdAdo.CommandText = "UPDATE table SET Memo = ? WHERE Field = 'a value'"
Set pMemo = cmdAdo.CreateParameter("Memo", ...)
pMemo.Size = Len(sMemoData)
pMemo.Value = ""

While Len(sMemoData) > 254
    pMemo.AppendChunk Left(sMemoData, 254)
    sMemoData = Right(sMemoData, Len(sMemoData) - 254)
Wend

If Len(sMemoData) > 0 Then pMemo.AppendChunk sMemoData

cmdAdo.Parameters.Append pMemo

cmdAdo.Execute 

Tags: , , , , ,

Filed under:Troubleshooting, VB

Log4Net, custom PatternLayout

I was looking for a way to add my own parsers to the PatternLayout class, and found following solution:

public class CustomPatternLayout : PatternLayout {
        protected override PatternParser CreatePatternParser(string pattern) {
            PatternParser parser = base.CreatePatternParser(pattern);

            //usage: %CustomField or %cf (case-sensitive)
            parser.PatternConverters["CustomField"] =  typeof(CustomPatternConverter);
            parser.PatternConverters["cf"] =  typeof(CustomPatternConverter);

            return parser;
        }
    }
Filed under:.Net, C#, Examples, Tips & Tricks

Select All Text In A MaskedTextBox On Enter

I encountered something weird yesterday evening.  In a MaskedTextBox, I wanted to select the entire text when a user enters the box, using the SelectAll method in an Enter event handler.  It didn’t work…

Fortunately, we have Google! After a quick search I found someone with the same problem and a solution.  By simply invoking (and postponing) the SelectAll call, it will work.  The MaskedTextBox has its own selection thing going on in it’s Focus event handler, that’s why just doing SelectAll doesn’t work.

Here’s what you must do: (C#)

private void txtMaskedTextBox_Enter(object sender, EventArgs e) {
    this.BeginInvoke( (MethodInvoker) delegate() {
        txtMaskedTextBox.SelectAll();
    } );
} 

You can’t use anonymous delegates in VB.Net 2005 (don’t know if you can in VS 2008), so you must create a new delegate and method.  But you can make it more generic at the same time, because I’ve also seen normal TextBoxes behaving like this from time to time.

Private Delegate Sub SelectAllInvoker(txtBox As TextBoxBase)

Private Sub SelectAll(ByVal txtBox As TextBoxBase)
    txtBox.SelectAll()
End Sub

Private Sub txtMaskedTextBox_Enter(ByVal sender As Object, ByVal e As EventArgs)
    Me.BeginInvoke(New SelectAllInvoker(AddressOf SelectAll), _
                   DirectCast(sender, TextBoxBase))
End Sub 
Filed under:.Net, C#, Tips & Tricks, VB