WPF ContextMenu Design. How to set Background in WPF MenuItem? - wpf

I create popup menu like this.
<DockPanel.ContextMenu>
<ContextMenu Background="#CD252220" Opacity="0.95" Foreground="LightGray" BorderBrush="DarkGray">
<MenuItem Header="_Save Image..." x:Name="btSave" IsEnabled="False" Click="btSave_Click" Style="{StaticResource MyStyle}">
<MenuItem.Icon>
<Image Source="icons/save.png" Width="16" Height="16" Style="{StaticResource IconStyle}"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</DockPanel.ContextMenu>
Why left-side of this menu is WHITE????? It'll be a #CD252220 color or transparent, bun not white!!!!!!
How to fix it? :)
http://itrash.ru/idb/40e872e71346dcf9bd58ba8aec0b2a17/omenu.png.html - menu screenshot
P.S. In XP it's OK. Menu is White only on Vista (don't have W7)

I find solution! You have to just set property OverridesDefaultStyle in Style-defenition section ;)
<Style x:Key="{x:Type ContextMenu}" TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="#CD222120" CornerRadius="7, 7, 8, 8" BorderBrush="DarkGray" BorderThickness="2" Opacity="0.96">
<StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" Margin="5,4,5,4"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="{x:Type MenuItem}">
<Border Name="Border" >
<Grid>
<ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>

If you will declare a custom style for your context menu, This way it will be same for all OS.

Related

Text inside SliderThumbStyle

So this is my SliderThumbStyle Style:
<Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Border Name="outerBorder"
Background="{DynamicResource LabelDisableForegroundColor}"
BorderBrush="{DynamicResource LabelDisableForegroundColor}"
Height="20"
Width="20"
Opacity="1"
BorderThickness="2"
CornerRadius="8"/>
<TextBlock x:Name="sliderValue"
FontSize="11"
Foreground="Silver"
Text="{Binding }"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And as you can see i put inside the Thumb a simple TextBlock in oder to see the current Slider value
What i need to put inside the Text property:
Text="{Binding }"
This should work provided that the Thumb is a visual child of the Slider:
<TextBlock Text="{Binding Value, RelativeSource={RelativeSource AncestorType=Slider}}" />

WPF Button style with Image

I want to create a style for button with different images inside. I try to do following:
<Style TargetType="Button"
x:Key="PaintButton">
<Setter Property="Width"
Value="40"></Setter>
<Setter Property="Height"
Value="40"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="3"
BorderThickness="2"
BorderBrush="Green">
<Image Source="{TemplateBinding Button.Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and try to use:
<Button Content="images/pen.png"
HorizontalAlignment="Left"
Style="{DynamicResource PaintButton}" />
but images is not shown. Why and how to do it correctly?
The "Image" is not a correct source for another Image.
Either use BitmapImage as Button's contents or use ContentPresenter in the template.
Option 1.
<Button Style="{StaticResource PaintButton}">
<BitmapImage UriSource="Back_Forward.png"/>
</Button>
Option 2.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="3"
BorderThickness="2"
BorderBrush="Green">
<ContentPresenter Content="{TemplateBinding Button.Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Please try this
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel Orientation="Horizontal">
<Grid Height="30" Width="30" Background="{TemplateBinding Background}"/>
<TextBlock Text="{TemplateBinding Content}" TextAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Button Name="btnPrintCard" Margin="2" Content="Print Card">
<Button.Background>
<ImageBrush ImageSource="images/ic_print_black_48dp.png"/>
</Button.Background>
</Button>

How to configure Contentpresenter in nested ControlTemplate?

I have the following code:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter .../>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
I need button inside template for binding possibility. The nested template defines the appearance.
The question: <ListBoxItem Content="Start"/> does not work with code above. I need something like root Contentpresenter that refers to Contentpresenter inside button template. How can I do this?
Thanks in advance!
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=Content}"/>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>

Binding selectedItem ListBox of Radio buttons in combobox popup

Ok, so my question is kind of convoluted, so I'll try to be as clear as possible. Because a collection of radio buttons does not have a 'SelectedItem/Value' property, I have collected my radioButtons into a ListBox, based on some XAML I found online. Now, in order to save space on the UI, that ListBox is taking over the content of a ComboBox popup. (So when you click the comboBox, what drops down is a list of radiobuttons in a WrapPanel.) I have been able to successfully bind the RadioButton listbox control by itself to an itemssource and bind selected value to a property, but once inside the combo box, I cannot seem to get the selected value binding to work properly, (ItemsSource still works fine).
<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="White"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Background="Transparent" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderThickness="1" Background="Transparent">
<RadioButton Focusable="False" Width="120"
IsHitTestVisible="False"
Content="{Binding Name}"
IsChecked="{TemplateBinding IsSelected}">
</RadioButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border BorderThickness="0" Padding="0" BorderBrush="Transparent" Background="Transparent" Name="Bd" SnapsToDevicePixels="True">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RadioButtonCombo" TargetType="ComboBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
DataContext="{TemplateBinding ItemsSource}"
Content="{Binding ElementName=DropDownContent, Path=SelectedItem.Name}"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press" />
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="WhiteSmoke"
BorderThickness="1" BorderBrush="Black"/>
<ListBox Name="DropDownContent" Style="{StaticResource RadioButtonList}"
Width="{TemplateBinding MaxWidth}"
SelectedValue="{Binding Path=SelectedValue, RelativeSource={RelativeSource TemplatedParent}}"
ItemsSource="{TemplateBinding ItemsSource}">
</ListBox>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
My use of that looks like this:
<ComboBox Name="SourceComboCtl"
Text="Source"
SelectedValuePath="CodeId"
DisplayMemberPath="Name"
SelectedValue="{Binding Path=SourceCode}"
Style="{StaticResource RadioButtonCombo}"
Width="60"
MaxWidth="150" />
I'm a bit confused why you'd first overwrite a ListBox to display RadioButtons, then overwrite a ComboBox to use a ListBox to display RadioButtons
Why not just overwrite ComboBox.ItemTemplate and skip the ListBox alltogether? ComboBox has SelectedItem/Value too
Here's my RadioButtonListBox Style. I simply changed where it says ListBox to say ComboBox
<Style x:Key="RadioButtonComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ComboBoxItem}" >
<Setter Property="Margin" Value="2, 2, 2, 0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="Transparent">
<RadioButton IsHitTestVisible="False" Focusable="false"
Content="{TemplateBinding ContentPresenter.Content}"
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>

wpf textbox flat border style

need to have flat border style for wpf based textbox... really surprised to see there is no easy way to get this like was in winforms textbox BorderStyle.FixedSingle
is there any easy way to get this done for wpf textbox
The way to do this is to use a control template to draw the border yourself. You can do this in many different ways, heres a couple for you to look at.
The quick hack approach:
<TextBox>
<TextBox.Template>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Rectangle Stroke="{StaticResource ResourceKey=detailMarkBrush}" StrokeThickness="1"/>
<TextBox Margin="1" Text="{TemplateBinding Text}" BorderThickness="0"/>
</Grid>
</ControlTemplate>
</TextBox.Template>
</TextBox>
and then theres using resources...
<ResourceDictionary>
<Color x:Key="detailMark">#FFA1A9B3</Color>
<SolidColorBrush x:Key="detailMarkBrush" Color="{StaticResource ResourceKey=detailMark}" />
<Style x:Key="flatTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Rectangle Stroke="{StaticResource ResourceKey=detailMarkBrush}" StrokeThickness="1"/>
<TextBox Margin="1" Text="{TemplateBinding Text}" BorderThickness="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
and then you can use the style:
<TextBox Style="{StaticResource ResourceKey=flatTextBox}" />
<TextBox BorderThickness="1" BorderBrush="Black">
just try this by black or gray
This is better way to me, make a custom template with border, to override the default one.
And most important make ScrollViewer named PART_ContentHost, to fit inner TemplatePart, and for any other features work like default.
simular to example from MSDN:
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border CornerRadius="2" Padding="2" Background="#19212F" BorderBrush="Red" BorderThickness="1">
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources