Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

28 July 2010

User Control Design Time Detection

Today, I created a wizard application in WPF/C#.  Each "page" of the wizard is a user control.  Each user control is largely autonomous, each having a pointer to a singleton instance DataManager class that persists data between the controls and parent window.  When a control is made visible, it checks the values of the DataManager class, to ensure the requisite values are available, etc.

The "page" controls are not instantiated on-demand, for reasons I will not discuss here.  When viewing the main window in the WPF designer, all of the user controls that perform data verification in their IsVisibleChanged event handler cause the WPF designer rendering to fail, although I did get several MessageBoxes containing the various validation error messages.  (At least I know those work well!)

The solution is to wrap all validation logic in an IF statement that checks to see if the control is being rendered in a designer.  It we are indeed in design time, the validation logic is stepped over.

private void UserControl_IsVisibleChanged(
    object sender, 
    DependencyPropertyChangedEventArgs e)
{
    if (DesignerProperties.GetIsInDesignMode(this)
        || this.Visibility != Visibility.Visible)
        return;

    // Validation logic here...
}

20 July 2010

Reverse TextIndent (Outdent) for FlowDocument

WPF FlowDocuments are extremely useful and format very nicely, so long as you are writing plain text.  The tag kindly provides a TextIndent attribute, to indent the first line of the paragraph.  But, what about formatting for nested code?

Margin doesn't look kindly upon inserting negative values, but TextIndent gladly accepts them.  Using a combination of a negative TextIndent and a matching, positive left margin, the Paragraph is coaxed into outdenting the first line.  This visually appears that the first line is even with the other paragraphs, and the following lines are indented.

<paragraph 
            margin="25,0,0,0"
            textindent="-25"
            FontFamily="Courier">
    First Line
    Second line
    Third Line
</paragraph>

Produces the following:

First Line
    Second Line
    Third Line

Admittedly, this works well for the first indent, but any further indentations must be handled with a bit of creativity. I will leave you to decide how to best handle that situation.

15 July 2010

Format Document - Run Frustrations

I have been using FlowDocument, to create C# training materials, because it looks nice as a presentation, but can include interactive controls embedded in BlockUIContainer.  It looks great, the interactive portions are perfect for the students, and everything is peaches and cream. That is, until I press Ctrl+E Ctrl+D to clean up the XAML using Visual Studio's Format Document tool.

I am using , etc., to reflect the default text colors seen in Visual Studio.  Format Document insists on inserting a white space following every tag.  This does a great job of reducing readability of things like array declarations:

This:  string[] s = new string[]{...}
Becomes: string [] s = new string []{...}

I know one line of code doesn't look like a big deal, but when you have something more complex, such as the following tuple declaration, everything gets jumbled together in a hurry.  This is not good for my students, who are unfamiliar with syntax and proper code formatting.

Tuple &lt; int , string , double , Tuple &lt; string [], int []> > t =
    new Tuple &lt; int , string , double , Tuple &lt; string [], int []> >(
        13, "Friday the 13th", 65.0185d,
        Tuple .Create&lt; string [], int []>(
            new string [] {"Jason", "Freddy", "Michael"},
            new int []{13, 14, 152}
        )
    );

If you have any solutions, please post them here, and I will include it in this post!

01 July 2010

Masking Drag & Drop Hit Test in WPF

While creating WPF demonstration code, I decided to use the classic DoDrag() method, to perform drag and drop functions.  When dropping objects on both a Canvas and Border object, DoDrag() unexpectedly and consistently returned Effects.None.

The solution was easy: the Canvas and Border objects had no Fill.  DoDrag's hit test was failing, because there was no physical rendering of the Canvas or Border at the mouse position!  The object must be filled, to return a positive hit test.  Using the "Transparent" brush  or a solid color with 00 alpha works, too.

Note, borders are considered filled areas, and return a positive hit.  You can use this to your advantage, but I'm not sure why you would ever drag and drop something on a border, unless it is very thick.  You could use a border as a drop mask, to return different Effects result, over certain areas of an object.