Archive

Posts Tagged ‘Samples’

HowTo: Load a XAML ResourceDictionary from a .NET assembly

Copying here my answer at:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/11a42336-8d87-4656-91a3-275413d3cc19

What seems to work for me is the following (copying from the source code of http://ClipFlair.codeplex.com [check out the FlipPanel project under “Client” subfolder])

note

I’m using Build Action = "Page" and Custom Tool="MSBuild:Compile" at the properties of Themes\DropDownTheme.xml and Themes\RotateHorizontalTheme.xaml, as was for Themes\Generic.xaml. Seems to work OK (probably this is faster at runtime compared to setting Build Action to Resource and telling it to not build it)

according to http://stackoverflow.com/questions/145752/what-are-the-various-build-action-settings-in-vs-net-project-properties-and-wh the Build Action = "Page" compiles the XAML into BAML (this seems to also apply to Silverlight 5)

* FlipPanel project, Themes\Generic.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary 
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> </ResourceDictionary.MergedDictionaries>
<Style TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel Project, Themes\RotateHorizontalTheme.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ControlTemplate x:Key="FlipPanel_RotateHorizontalTemplate" 
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_RotateHorizontalStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel Project, Themes\DropDownTheme.xaml

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel">
 
  <ControlTemplate x:Key="FlipPanel_DropDownTemplate" 
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_DropDownStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_DropDownTemplate}"/> </Style> </ResourceDictionary>

* FlipPanel.Silverlight.Demo project, FlipPanelTest.xaml

<UserControl x:Class="FlipPanelTest.FlipPanelTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:flip="clr-namespace:FlipPanel;assembly=FlipPanel" >
 
  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary 
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> <ResourceDictionary
Source="/FlipPanel;component/Themes/DropDownTheme.xaml" /> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White" Width="400"> <Grid.RowDefinitions> <RowDefinition Height="300"></RowDefinition> <RowDefinition Height="300"></RowDefinition> </Grid.RowDefinitions> <flip:FlipPanel x:Name="panel1" Grid.Row="0" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_DropDownTemplate}" >
<!-- Style="{StaticResource FlipPanel_DropDownStyle}" -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip1_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel> <flip:FlipPanel x:Name="panel2" Grid.Row="1" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_RotateHorizontalTemplate}" >
<!-- Style="{StaticResource FlipPanel_RotateHorizontalStyle}" -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>
<flip:FlipPanel x:Name="panel3" Grid.Row="2" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White" >
<!-- using default style here -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>



</Grid> </UserControl>

 

Note that I decided to prefix names with "FlipPanel_", not sure if there’s some better way (using XAML namespaces somehow) to avoid any conflicts when merging the dictionaries and resolving the resouces with "{StaticResource …}"

Also note that in each theme file I also provide a Style (that sets the corresponding Template property of the FlipPanel conrol) that one can use instead of using the Template directly. At that Style more FlipPanel control properties could be set to values appropriate for that template (the template defines a skeleton and the style dresses the pirate [skeleton] as somebody cleverly pointed out).

Note that Generic.xaml merges and uses the templat from one of the themes. Couldmake copies of files similar to Generic.xaml and reference the same template but with different values in the Style for other properties to make variations without resorting to Copy/Paste when multiple Themes use the same Template but restyle it a bit.

Another important note is that at Generic.xaml you must not use x:Key="FlipPanel_DefaultStyle" or anyother key at the default style, or the command

        public FlipPanel()
        {
            DefaultStyleKey = typeof(FlipPanel);
        }

won’t load the default style (which is needed when you don’t provide a Template or Style value at the consumer XAML (FlipPanelTest.xaml). Probably one can modify it to load a style by name instead of just by type (probably the issue was that it found multiple named styles applying to that type [both FlipPanel_RotateHorizontalStyle and FlipPanel_DefaultStyle] in the Generic.xaml), but removing the Key and using an unnamed style seems to do the trick.

Validating E-mails using Regular Expressions in Java

To sum up the discussion at http://stackoverflow.com/questions/1360113/is-java-regex-thread-safe/, you can reuse (keep in static variables) the compiled Pattern(s) and tell them to give you new Matchers when needed to validate those regex pattens against some string:


import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Validation helpers
 */ 
public final class Validators {  

  private static final String EMAIL_PATTERN = 
    "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*
     @[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
  
  private static Pattern email_pattern;  

  static {  
    email_pattern = Pattern.compile(EMAIL_PATTERN);
  }

  /**
   * Check if e-mail is valid 
   */   
  public static boolean isValidEmail(String email) {    
    Matcher matcher = email_pattern.matcher(email);
    return matcher.matches(); 
  }

}

(Note: the EMAIL_PATTERN string should be put in a single line)

For the RegEx pattern used, see the article at http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/ and the user comments (and useful links) posted there.

Update (20120715): previous pattern wasn’t accepting “-” in the domain name

Categories: Posts Tags: , , , ,

Gotchas at Wait for a shelled app to finish (with/out timeout) with .NET

I came across a useful Microsoft Support sample called “How to wait for a shelled application to finish by using Visual Basic 2005 or Visual Basic .NET” at http://support.microsoft.com/kb/305368

However, note that there are several gotchas with the code supplied there (just informed Microsoft on that, hope they take notice). Also the article points to C# and to C++ versions of the sample that obviously need the same fixes

1) there’s an issue in both the first sample (wait indefinitely) and the 2nd one (wait with timeout)

‘Wait for the process window to complete loading.
p.WaitForInputIdle()
‘Wait for the process to exit.
p.WaitForExit()

Why wait for input idle first? The process might never enter idle state and exit before that. According to http://msdn.microsoft.com/en-us/library/8d7363e2(v=VS.90).aspx you might get exception from WaitForInputIdle:

 

Exception Condition
InvalidOperationException The process does not have a graphical interface.
-or-
An unknown error occurred. The process failed to enter an idle state.
-or-
The process has already exited.
-or-
No process is associated with this Process object.

I suppose it’s best to avoid calling WaitForInputIdle at all since you just care for WaitForExit there.

 

2) even WaitForExit can throw exceptions that the code should check for according to http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx

Exception Condition
Win32Exception The wait setting could not be accessed.
SystemException No process Id has been set, and a Handle from which the Id property can be determined does not exist.
-or-
There is no process associated with this Process object.
-or-
You are attempting to call WaitForExit for a process that is running on a remote computer. This method is available only for processes that are running on the local computer.

3) The support article doesn’t mention what WaitForExit(timeout) doc (http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx) says about “infinite” timeout:

Note

In the .NET Framework version 3.5 and earlier versions, the WaitForExit overload waited for MaxValue milliseconds (approximately 24 days), not indefinitely. Also, previous versions did not wait for the event handlers to exit if the full MaxValue time was reached.

Also it seems the documentation for “WaitForExit(timeout)” doesn’t mention there’s a Timeout.Infinite constant that has the value –1 to use for such infinite timeouts (found it from the doc of Thread.Join): http://msdn.microsoft.com/en-us/library/system.threading.timeout.infinite(v=VS.90).aspx

4) The sample fails to call Close and thus keeps on spending resources for handle tracking (and “locking” those handle ids obviously although it’s not as easy as in old CPUs and OS versions to run out of handles I hope).

Quoting http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:

When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.

Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Instead, the handle can be used only to access the operating system’s information about the process resource. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close frees the memory allocated to the exited process.

Also note that it could have a “Using” clause when defining the new process object (instead of Dim) instead of explicitly having to call “Process.Close” at the end to free up resources, as noted at http://msdn.microsoft.com/en-us/library/system.diagnostics.process.close(v=VS.90).aspx

The Close method causes the process to stop waiting for exit if it was waiting, closes the process handle, and clears process-specific properties. Close does not close the standard output, input, and error readers and writers in case they are being referenced externally.

NoteNote:

The Dispose(Boolean) method calls Close. Placing the Process object in a using block disposes of resources without the need to call Close.

5) Other issue is at the 2nd sample (wait with timeout). It doesn’t mention having to call WaitForExit() again with no params after the WaitForExit(timeout) at the case where standard output has been redirected to async event handlers (should mention this case for completeness)

Quoting http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:

When standard output has been redirected to asynchronous event handlers, it is possible that output processing will not have completed when this method returns. To ensure that asynchronous event handling has been completed, call the WaitForExit overload that takes no parameter after receiving a true from this overload. To help ensure that the Exited event is handled correctly in Windows Forms applications, set the SynchronizingObject property.

%d bloggers like this: