We demonstrated creating a WPF Window from an External Command of Revit Addins before either through creating a WPF window on the fly and hosting a User Control into it or through converting a WPF Application project to a Revit Class Library then creating a WPF window from an XMAL template directly.
We also made the created-on-the-fly WPF window/control look good through tweaking many properties of both the host window and the hosted control and added some fancy effects to both the background of the window/control and a particular button.
A cool feature about WPF is that we can make the same user control/window and its buttons look different but all cool, or have different nice skins at different times. We can achieve the goal through applying a theme to the whole WPF user control or window.
We can apply themes in many ways. The themes can be from some external loose XMAL files or from some internal compiled/embedded theme XMAL resources either in the same assembly or in separate ones. And we can statically specify the theme for the WPF Control/Window in the XMAL files or dynamically merge the theme definitions into its resource dictionaries with code.
We are going to add some skin to the User Control that we have demonstrated before through specifying a theme embedded into a theme pack/assembly which is referenced into the project.
A theme pack is actually a theme governing .NET assembly having one or more theme XAML files parsed, compiled (into .BAML format) and packed into it. To load a theme from compiled resource, we need to add a reference to the theme pack first into the project and merge the theme with the application resources next.
A sample theme pack, ThemesPack.dll, has been created for this purpose and referenced into the project as the following Solution Explorer capture demonstrates.
Now we add the theme Source as a ResourceDictionary to the MergedDictionaries of the ResourceDictionary of the Resources of the UserControl. The URI source path is pretty similar to that of an embedded theme in the host assembly itself. Only the assembly name is different as the highlighted code in the following UserControl XMAL definition file shows:
<UserControl x:Class="RevitAddinCSWPF.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ThemesPack;component/Themes/WhistlerBlue.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Rectangle Width="Auto" Height="Auto">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Azure" Offset="0.0" />
<GradientStop Color="Orchid" Offset="0.15" />
<GradientStop Color="Purple" Offset="0.25" />
<GradientStop Color="RosyBrown" Offset="0.5" />
<GradientStop Color="Purple" Offset="0.75" />
<GradientStop Color="Orchid" Offset="0.85" />
<GradientStop Color="Azure" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Button Name="button1" Click="button1_Click" Height="35" Width="200">
<Button.Template>
<ControlTemplate TargetType="Button" >
<Grid Background="#00FFFFFF">
<Ellipse Fill="CadetBlue"/>
<ContentPresenter x:Name="content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
Hello from WPF
</Button>
<!--<Button Margin="53,49,34,0" Name="button1" Click="button1_Click" Height="35" VerticalAlignment="Top">Hello from WPF</Button>-->
<Button Height="27" HorizontalAlignment="Left" Name="button2" VerticalAlignment="Top" Width="24">TL</Button>
<Button Height="27" HorizontalAlignment="Left" Name="button3" VerticalAlignment="Bottom" Width="24">BL</Button>
<Button Height="27" HorizontalAlignment="Right" Name="button4" VerticalAlignment="Top" Width="24">TR</Button>
<Button Height="27" HorizontalAlignment="Right" Name="button5" VerticalAlignment="Bottom" Width="24">BR</Button>
<Button Height="27" HorizontalAlignment="Left" Margin="53,0,0,33" Name="button_Cancel" VerticalAlignment="Bottom" Width="84" Click="button_Cancel_Click">Cancel</Button>
<Button Height="27" HorizontalAlignment="Right" Margin="0,0,34,33" Name="button_OK" VerticalAlignment="Bottom" Width="84" Click="buttonOK_Click">OK</Button>
<CheckBox Height="16" Margin="30,5.52,150,0" Name="checkBox1" VerticalAlignment="Top">CheckBox</CheckBox>
<CheckBox Height="16" Margin="30,27,150,0" Name="checkBox2" VerticalAlignment="Top">CheckBox</CheckBox>
<RadioButton Height="16" Margin="130,5,50,0" Name="radioButton1" VerticalAlignment="Top">RadioButton</RadioButton>
<CheckBox Height="16" Margin="30,49,150,0" Name="checkBox3" VerticalAlignment="Top">CheckBox</CheckBox>
<RadioButton Height="16" Margin="130,27,50,0" Name="radioButton2" VerticalAlignment="Top">RadioButton</RadioButton>
<RadioButton Height="16" Margin="130,49,50,0" Name="radioButton3" VerticalAlignment="Top">RadioButton</RadioButton>
</Grid>
</UserControl>
Now the project should build well and we are ready to give it a try immediately by pressing the F5 since Revit Addin Wizard (RevitAddinWizard) has already set up the debugging settings for us automatically.
After the ExtCmd2 ribbon button of the RevitAddinCSWPF ribbon panel is clicked, the WPF Window hosting the User Control shows up with the cool whistler blue skin this time:
A few check boxes and radio buttons have also been added to the WPF User Control to make the skin effects appear clearer and nicer.
NOTE: In case the ThemesPack.dll cannot be found by Revit, please copy it to the Revit program folder.
More articles about WPF and Revit Addin/API can be expected soon. Please stay tuned.
RevitAddinWizard may provide a few coders to address some WPF usage cases in the near future.
Recent Comments