Similar WPF Windows - wpf

I have WPF Application and 2 Windows with similar structure (everything is same:menu, Title, Toolbar, only in the middle one stack panel is other, in one window has 10 TextFields,Button and other controls,and other one has other controls in this stack panel.I can copy one window in other, but I duplicate code.How can i solve this problem?Thanks.

One way would be to create a ControlTemplate and/or Style for the Window.
<ControlTemplate x:Key="MyWindowTemplate" TargetType="Window">
<AdornerDecorator>
<DockPanel>
<!-- Your toolbar content and other shared content -->
<!-- The dynamic content is loaded into the content presenter: -->
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</DockPanel>
</AdornerDecorator>
</ControlTemplate>
<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}" BasedOn="{StaticResource {x:Type Window}}">
<Setter Property="Template" Value="{StaticResource MyWindowTemplate}" />
</Style>
When you now create a window instance, you apply the style to the window and add some content into the content property and (if necessary) some ContentTemplate.

Create just one window and:
Add all the common controls required for both the screens.
Add the different stack panels in the same place and bind their visibility to the same flag.
Implement the InverseBooleanConverter and bind that to one of the stack panel's visibility based on how you are going to handle the flag.
Handle the flag before launching the view i.e. set it to true or false based on which window you are showing at that time.

Related

Why is my XAML control losing properties when applying a style template to it?

I'm trying to style this button, and I even though I state the height it should be in my XAML, the template in the styling seems to get rid of it.
Note: I am aware I can just have a style with no template, but I need the template because I'm using multiple themes / style files.
Control:
<Button Style="{DynamicResource basicButton}"
Height="50">
<Canvas...>
<Path... />
</Canvas>
</Button>
Styling:
<Style x:Key="basicButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{DynamicResource solid_single_mainColor}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is this expected behavior? I intent to re-use this button style, so I need to be able to give it a height in the XAML. What am I missing? How can I give each new button I create a different height?
The problem is likely coming from the Canvas that you are placing inside the Button. In many cases a Canvas will have unbounded size unless you explicitly clip it. The Height of the Button itself isn't affected by its template as layout measurement will use the explicit value you have set but you may not be able to tell visually what size the Button itself is.

WPF form inheritances issue

I have some questions concerning the issue of form inheritance in WPF.
I have read that there is no visual inheritance in WPF Forms.
I would like to write my project as a base form, with other forms inheriting from it.
Some possible solutions were to use UserControl, and use it inside the son form.
The problem is that I have to define it again and again in every new form that inherits the base one.
Can I implement it another way, without defining it in the son-form?
You can use a style to handle this with less markup than a UserControl (you just have to set Style="{StaticResource myWindowStyle}" in every Window element). Using that style you can override the Template of a window, putting whatever chrome you like around the window content. Add a ContentControl with Content="{TemplateBinding Content}" wherever you want your sepcific Window's content to appear.
Unfortunately you can't apply this to all Windows easily, because setting a generic style will apply only to the base Window control, and each of your application's windows will be of a type that derives from Window.
EDIT: If you want to specify templated controls in your Window, you can do something like the following with your style:
<Style x:Key="MyWindowStyle" TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<StackPanel>
<Button>This button will appear on every window</Button>
<ContentControl Content="{TemplateBinding Content}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Toolbar - Custom Style

I want to change the standard style of a wpf toolbar. I use the following Style in the Control Resources, which works fine:
<Style x:Key="{x:Type ToolBar}" TargetType="{x:Type ToolBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolBar}">
<Border>
<DockPanel VerticalAlignment="Stretch" Height="38">
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
However, if i add items to a toolbar, these items are not shown:
<ToolBar x:Name="myToolbar">
<Label>test</Label>
</ToolBar>
I do NOT want to add the items in the template, but in a specific toolbar which uses that template.
Can anyone give me a hint?
The problem is that you replaced the toolbar's control template with your own. But you haven't specified in that template where items should be shown. Typically you would do it either by adding an ItemsPresenter:
<ControlTemplate TargetType="{x:Type ToolBar}">
<Border>
<DockPanel VerticalAlignment="Stretch" Height="38">
<ItemsPresenter/>
</DockPanel>
</Border>
</ControlTemplate>
Or by setting IsItemsHost="True" on a panel inside the template:
<ControlTemplate TargetType="{x:Type ToolBar}">
<Border>
<DockPanel IsItemsHost="True" VerticalAlignment="Stretch" Height="38">
</DockPanel>
</Border>
</ControlTemplate>
But, if you try to replace the items panel for the ToolBar (as in my second example), it will not work, because ToolBar expects the ToolBarPanel to be the items panel.
A template defines how a control is rendered, for some controls everything is within the template for others the control expects to find named elements within the template which it will manipulate. If you look at the ToolBar template you can see that the toolbar expects to find an element named PART_ToolBarPanel and an element named PART_ToolBarOverflowPanel within the template:
http://msdn.microsoft.com/en-us/library/aa970772.aspx
For example, it needs to locate the element named PART_ToolBarPanel in order to add the items to the toolbar.
If you want to add new elements to the toolbar template, typically you would start by copying the existing template, then start adding / removing element.

Attach xaml style to element without explicitly stating it

I have a problem styling/templating an AccordionItem in the accordion control from the silverlight toolkit. For some reason, the child controls are Horizontally Aligned Left. The only way I can get to fix this is to edit the ExpandableContentControlStyle on the AccordionItem.
The style is located below:
<Style x:Key="ExpandableContentControlStyle1" TargetType="layoutPrimitivesToolkit:ExpandableContentControl">
<Setter.Value>
<ControlTemplate TargetType="layoutPrimitivesToolkit:ExpandableContentControl">
<ContentPresenter x:Name="ContentSite" Cursor="{TemplateBinding Cursor}" Margin="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="Stretch" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now my problem is that to have this style being attached to the AccordionItem, I have to set it:
<layoutToolkit:Accordion HorizontalAlignment="Stretch">
<layoutToolkit:AccordionItem Header="Hello" BorderBrush="{x:Null}" ExpandableContentControlStyle="{StaticResource ExpandableContentControlStyle1}"/>
<layoutToolkit:AccordionItem Header="Haha" BorderBrush="{x:Null}"/>
</layoutToolkit:Accordion>
But those AccordionItem will be generated from an ItemSource. What I'd like to do is to have that style be applied to the generated AccordionItem without setting it.
PS. The above problem can become obsolete if I can just find out how to edit the (ContentPresenter x:Name="ContentSite") from the parent Accordion. I cannot edit it from none of the following template properties:
ContentTemplate
ItemContainerStyle
AccordionButtonStyle
ItemsPanel
ItemTemplate
If anyone knows what is going on with that, I'd appreciate the help or you can just help with styling of multiple elements.
I haven't used the Accordion control myself, though typically you set the ItemContainerStyle to the style you want for each item in the list. For instance, if you wanted a specific ListBoxItem style on a ListBox, you set the ItemContainerStyle to the ListBoxItem style you want. I glanced at the source for the Accordion and this seems to hold true for that control as well. Try setting the ItemContainerStyle property of the Accordion to your ExpandableContentControlStyle1.
<layoutToolkit:Accordion
HorizontalAlignment="Stretch"
ItemContainerStyle="{StaticResource ExpandableContentControlStyle1}">
</layoutToolkit:Accordion>
To set the style outside of the control itself, create a style for the Accordion. If you're using Silverlight 4, you can use implicit styles. Put the following style in the <UserControl.Resources> section of your page.
<Style TargetType="layoutToolkit:Accordion">
<Setter Property="ItemContainerStyle" Value="{StaticResource ExpandableContentControlStyle1}"/>
</Style>
Otherwise, with Silverlight 3 you'll have to explicitly give the style a Key and explicitly set the style on the Accordion control.
<Style x:Key="Control_Accordion" TargetType="layoutToolkit:Accordion">
<Setter Property="ItemContainerStyle" Value="{StaticResource ExpandableContentControlStyle1}"/>
</Style>
<layoutToolkit:Accordion
Style="{StaticResource Control_Accordion}"
HorizontalAlignment="Stretch">
</layoutToolkit:Accordion>

ItemContainerStyle in Custom Control Derived From ListBox

Please bear with me Silverlight Designer Gurus, this is compicated (to me).
I'm creating a custom control which derives form the Silverlight 3.0 ListBox. In an effort not to show tons of code (initially), let me describe the setup.
I have a class library containing a class for my control logic. Then I have a Themes/generic.xaml that holds the styling details. In generic.xaml, I have a style that defines the default layout and look for the ListBox where I'm setting a values for the Template, ItemsPanel and ItemTemplate.
In my test app, I add my control on to MainPage.xaml and run it and it works great. I dynamically bind data to my control and that works fine.
Now I want to set the ItemContainerStyle for my derived control. If I create a style in the MainPage.xaml file and set the ItemContainerStyle property to that control as in:
<dti:myControl x:Name="MyControl1" ItemContainerStyle="{StaticResource MyListBoxItem}"
Height="500"
Width="200"
Margin="10"
Background="AliceBlue"
/>
It works as expected.
However, I'd like to do this in the class library or, more specifically, in generic.xaml. I tried to this Setter to my current Style:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<ControlTemplate>
<Grid Background="Red" Margin="3">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="Stretch" Margin="3"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
And it fails miserably with:
"System.ArgumentException: 'System.Windows.Controls.ControlTemplate' is not a valid value for property 'ItemContainerStyle'."
Note: This is not my actual style I'd like to use for ItemContainerStyle. I'm actually looking to plug in some VSM here for the various selected/unselected states of the a ListBoxItem (for a dynamically bound control).
So, to the question is how do I apply the ItemContainterStyle to my custom control when it's defined using generic.xaml? I do not want that property set when I actually use the control later on.
Thanks,
Beaudetious
You missed to put Style tag inside your Setter.Value. ItemContainerstyle explects a Style to ListBoxItem(Unless you subclassed ListBoxItem to your own derived version.)
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType=”{x:Type ListBoxItem}“ >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Red" Margin="3">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="Stretch" Margin="3"/>
</Grid>
</ControlTemplate>
<Setter.Value>
</Style>
</Setter.Value>

Resources