How to customize default context menu - wpf

In my WPF application I want to make my all textboxes cut, copy and paste restricted.
One way to do this is set ContextMenu ="{x:Null}"
But by doing this I will loose the spell check suggestions which I don't want to loose. Also In my application I have 1000 textboxes so I want to do this is in a more optimize way.
Any advice will be appreciated.

If all you need is menu items related to spell checking, you can refer to this MSDN article:
How to: Use Spell Checking with a Context Menu.
If you want to apply custom ContextMenu to multiple (but not all) textboxes:
<Window.Resources>
<ContextMenu x:Key="MyCustomContextMenu">
<MenuItem Header="Ignore All" Command="EditingCommands.IgnoreSpellingError" />
</ContextMenu>
</Window.Resources>
<Grid>
<TextBox Height="23" Name="textBox1" Width="120" SpellCheck.IsEnabled="True"
ContextMenu="{StaticResource MyCustomContextMenu}" />
</Grid>
If you want to apply custom ContextMenu to ALL textboxes:
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem
Header="Ignore All"
Command="EditingCommands.IgnoreSpellingError" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TextBox Height="23" Name="textBox1" Width="120" SpellCheck.IsEnabled="True" />
</Grid>
NOTE:
You can move the context menu resource to application level instead of the window level.
The MSDN article mentions to get menu items via C# code and not via XAML. I could easily port the "Ignore All" command to XAML (code snippets above), but for spelling suggestions, you will have to do some R&D.

Related

set visibility of multiple elements in XAML by one variable

when working on the design, i want to be a able to control visibility of multiple components i want to be able to control all of the isHidden from a single property.
so far my code looks like this
ignoreable="e d"
<StackPanel d:IsHidden=true>
...
</StackPanel>
<StackPanel e:IsHidden=false>
...
</StackPanel>
<StackPanel d:IsHidden=true>
...
</StackPanel>
<StackPanel e:IsHidden=false>
...
</StackPanel>
is there any way to control the visibility of all of the panels from a single variable?
so it will look like this
<StackPanel d:IsHidden=isVisibleVar>
...
</StackPanel>
<StackPanel e:IsHidden=isVisibleVarOther>
...
</StackPanel>
i'm aware of converters. i know how to do this at runtime, what i want to is have a fast way to switch between visibility of the two groups from one place, instead of search & replace
found a work around.
use a style for each group. then i only need to set the visibility in two locations.
<Style x:Key="MainButtonStyle"
TargetType="Button"
BasedOn= "{StaticResource BasicButton}">
<Setter Property="Visibility" Value="Visible"></Setter>
</Style>
<Style x:Key="SecButtonStyle"
TargetType="Button"
BasedOn= "{StaticResource BasicButton}">
<Setter Property="Visibility" Value="Hidden"></Setter>
</Style>
My answer may not be such a high sophisticated one and did not use only a "single variable", but it will do the trick (using two variables).
So at first you define two variables in your XAML. For example directly in the Window.Resources like:
<Window ...
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
>
<Window.Resources>
<system:Boolean x:Key="ShowInDemoMode">False</system:Boolean>
<system:Boolean x:Key="HideInDemoMode">True</system:Boolean>
</Window.Resources>
...
</Window>
or - if you have one - in your Style-ResourceDictionary
<ResourceDictionary ...
xmlns:system="clr-namespace:System;assembly=mscorlib"
>
<system:Boolean x:Key="ShowInDemoMode">False</system:Boolean>
<system:Boolean x:Key="HideInDemoMode">True</system:Boolean>
...
</ResourceDictionary>
Then you can use the two like this:
<StackPanel d:IsHidden="{StaticResource HideInDemoMode}">
...
</StackPanel>
<StackPanel d:IsHidden="{StaticResource ShowInDemoMode}">
...
</StackPanel>
<StackPanel d:IsHidden="{StaticResource HideInDemoMode}">
...
</StackPanel>
<StackPanel d:IsHidden="{StaticResource ShowInDemoMode}">
...
</StackPanel>
With this static resources you can easily switch between the visibility of your StackPanel items by changing the values of these two resources.
Remark:
Setting d:IsHidden to true or false is only active in DesignTime and will show the items when running your application, which is a major difference to your answer.

Why does my Ribbon Menu Button Popup disappear when I apply this Style?

Here is my XAML:
<Ribbon x:Name="ribbonMain" Height="200" ContextMenu="{x:Null}" VerticalAlignment="Top" ShowQuickAccessToolBarOnTop="False" >
<RibbonTab x:Name="ribbonTabMain" Header="Test Tab" ContextMenu="{x:Null}" >
<RibbonGroup x:Name="ribbonGroupMain" Header="Test Group" ContextMenu="{x:Null}">
<RibbonButton x:Name="ribbonButtonMain" Label="Test Button" ContextMenu="{x:Null}" />
</RibbonGroup>
<RibbonGroup x:Name="ribbonGroupMain2" Header="Test Group 2" ContextMenu="{x:Null}">
<RibbonMenuButton ContextMenu="{x:Null}" Name="ribbonMenuButtonMain" Label="Menu Button">
<RibbonMenuItem ContextMenu="{x:Null}" Name="ribbonMenuItemMain" Header="Menu Item"></RibbonMenuItem>
<RibbonMenuItem ContextMenu="{x:Null}" Name="ribbonMenuItemMain2" Header="Menu Item 2"></RibbonMenuItem>
</RibbonMenuButton>
</RibbonGroup>
</RibbonTab>
</Ribbon>
I then run this C# Code to get the Ribbon Menu Button Default Control Template:
string ribbonMenuButtonControlTemplate = XamlWriter.Save(ribbonMenuButtonMain.Template);
After that I set the x:Name and x:Key properties of the Control Template to something and then put that string of XAML in this:
<Style TargetType="RibbonMenuButton"
<Setter Property="Template">
<Setter.Value>
{DefaultControlTemplateHere}
</Setter.Value>
</Setter>
</Style>
Last I put that Style in my <Window.Resources>.
I wanted to alter the Style from there, but then I realized that the popup just wasn't working anymore.
I expected nothing to change. Seems I was mistaken.
Why does this happen?
Note:
I've tried running this code to see if the popup would open:
if (!ribbonMenuButtonMain.IsDropDownOpen)
{
ribbonMenuButtonMain.IsDropDownOpen = true;
}
With no Style applied that code runs fine and the popup opens.
But with the Style I get this exception:
System.InvalidOperationException: 'This Visual is not connected to a
PresentationSource.'
The XamlWriter.Save method has some serialization limitations that are mentioned here. One of them being that;
Common references to objects made by various markup extension formats, such as StaticResource or Binding, will be dereferenced by the serialization process. These were already dereferenced at the time that in-memory objects were created by the application runtime, and the Save logic does not revisit the original XAML to restore such references to the serialized output.
So your generated template is missing a TemplateBinding to the IsOpen property of the Popup:
<Popup ... IsOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsDropDownOpen}">
You may extract the default template including any bindings from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\System.Windows.Controls.Ribbon.dll using a decompiler such as for example dotPeek.

How To Make A WPF UserControl Act As A Container

I'm trying to create a Toolbar control that can group selected buttons with a border and a label. If there is already a built-in control that will do this then I could use that instead of building a UserControl.
If not, then what I'm wanting to build is a UserControl that would allow me to enter one-to-many of my ImageButton UserControls and set a GroupLabel text like below. Can this be done in WPF?
<User_Controls:ToolbarGroup GroupLabel="Entity">
<User_Controls:ImageButton ButtonText="Entity Setup"/>
<User_Controls:ImageButton ButtonText="New Entity"/>
</User_Controls:ToolbarGroup>
PS: I would post an image but this quirky forum won't allow me to post an image.
If i have got you correctly then I think you can achieve this way also, and on mouse eneter and leave event you can do the button click job.
for setting text you can use a grid and a label inside it to set the text, and Image buttons below it.
<UserControl x:Class="ABC.View.Oats"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Image Source="{Binding Image}" Stretch="Fill"/>
</Grid>
</UserControl>
I think what you're looking for is a GroupBox, it has a header property where you can set the label.
Something like this:
<GroupBox Width="300" Height="100">
<GroupBox.Header>
<Label>Text</Label>
</GroupBox.Header>
<StackPanel>
<Button Content="Button"/>
<Button Content="Button"/>
<Button Content="Button"/>
</StackPanel>
</GroupBox>
I would also recommend using the groupbox, it seems to be doing exactly what you want it to do and it looks neat. Here's some examples on how to use them: http://www.dotnetperls.com/groupbox-wpf
On the other hand, if you believe the groupbox is not sufficient, you could create a control that inherits from the groupbox and you could extend it and add whatever you need to it. It would look like this:
public class customGroupBox: GroupBox{
....Add whatever you need here
}
Thanks for the replies. I tried the GroupBox and it's not the layout we want because we want the label underneath the buttons and centered. I never could find a way to add a collection to the UserControl. Maybe I didn't ask the question right by calling it a container. The code below will work, but it's not elegant. I wanted something that would wrap the layout in a UserControl and allow me to add a variable number of buttons to each toolbar group.
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<User_Controls:ImageButton ButtonText="New 1"/>
<User_Controls:ImageButton ButtonText="New 2"/>
<User_Controls:ImageButton ButtonText="New 3"/>
</StackPanel>
<Label HorizontalAlignment="Center" Content="Group 1"/>
</StackPanel>
</Border>
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<User_Controls:ImageButton ButtonText="New 4"/>
</StackPanel>
<Label HorizontalAlignment="Center" Content="Group 2"/>
</StackPanel>
</Border>
</StackPanel>
One way to accomplish this is with a custom styled ItemsControl.
You can then reuse it and just bind it to different data.
Please forgive me, this is hand-typed...
In your resources...
<Style x:Key="ToolbarGroupItemsControlStyle" TargetType="ItemsControl">
...
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Grid>
... XAML to form your group with a binding to the
... group name
<ItemsPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ToolbarGroupItemTemplate">
<Grid>
... XAML and binding for each toolbar group item ...
</Grid>
</DataTemplate>
In your XAML...
<ItemsControl
Style="{DynamicResource ToolbarGroupItemsControlStyle}"
ItemsSource="{Binding ToolbarGroupItems}"
ItemTemplate="{DynamicResource ToolbarGroupItemTemplate"/>
If your resources above are at the application level, then you can place the ItemsControl above on any Window/UserControl you want.
Your ItemsSource will need to be a collection of a custom type you create that has bindings for the button text, etc.
I hope this is helpful.

WP7 Bing Maps Pushpin template with image doesn't show up

My ultimate goal is to have pushpins with custom images on a Bing Map in a WP7 app. I have created a control template and a map with a pushpin. Right now, I can get the default pushpins to show up, but nothing shows when I try to template it. Here's what I have right now:
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="PushpinControlTemplate" TargetType="my:Pushpin">
<Image Source="/Images/Pins/pin.png" />
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<my:Map Name="mapMain" CredentialsProvider="CredKey">
<my:Pushpin/>
</my:Map>
If I apply the PushpinControl template nothing shows up:
<my:Pushpin Template="{StaticResource BoaPushpinControlTemplate}" />
If I remove the template, it shows the default black shape.
I must be doing my template incorrectly, but I don't know what the problem is. Can I not have an image in the ControlTemplate?
If you arent using ItemSource binding on the Map then use simple content control approach
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
Or if you dynamically populating the push-pins use the below approach
<maps:Map x:Name="map" >
<maps:MapItemsControl ItemsSource="{Binding Collection}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
Even though this thread is a little bit old I'm going to post my suggestion:
Try out this link Working with Pushpins, it is working for me (create a new style and use it in pushpin declaration)
(App.xaml, do not forget the namespace!)
xmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps" >
<Application.Resources>
<Style TargetType="m:Pushpin" x:Key="PushpinStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="m:Pushpin">
<Image Width="24" Height="24" Source="path_to_pic" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(in the xaml there the map is)
<Grid x:Name="LayoutRoot" Background="Transparent">
<m:Map x:Name="Map" Mode="Aerial"
CredentialsProvider="CredKey">
<m:MapItemsControl x:Name="Content">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<m:Pushpin Location="{Binding Location}" Style="{StaticResource PushpinStyle}" />
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:Map>
</Grid>
If this isn't working check if the Build Action of your picture is set to content.
Took me a while to figure this out, so i hope i could help someone, despite the fact that this thread is old. ;)

Copy Context Menu for ListView Control

What is the best way to add "copy to clipboard" functionality to a ListView control in WPF?
I tried adding an ApplicationCommands.Copy to either the ListView ContextMenu or the ListViewItem ContextMenu, but the command remains disabled.
Thanks,
Peter
Here is an xaml sample of one of my attempts...
<Window.Resources>
<ContextMenu x:Key="SharedInstanceContextMenu" x:Shared="True">
<MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
</ContextMenu>
</Window.Resources>
<ListBox Margin="12,233,225,68" Name="listBox1" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=UpToSourceCategoryByCategoryId.Category}" ContextMenu="{DynamicResource ResourceKey=SharedInstanceContextMenu}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How should I set the CommandTarget in this case?
Thanks,Peter
It looks like you need a CommandBinding.
Here is how I would probably go about doing what you trying to do.
<Window.CommandBindings>
<CommandBinding
Command="ApplicationCommands.Copy"
Executed="CopyCommandHandler"
CanExecute="CanCopyExecuteHandler" />
</Window.CommandBindings>
<Window.Resources>
<ContextMenu x:Key="SharedInstanceContextMenu">
<MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
</ContextMenu>
<Style x:Key="MyItemContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContextMenu" Value="{StaticResource SharedInstanceContextMenu}" />
</Style>
</Window.Resources>
<ListBox ItemContainerStyle="{StaticResource MyItemContainerStyle}">
<ListBoxItem>One</ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
<ListBoxItem>Three</ListBoxItem>
<ListBoxItem>Four</ListBoxItem>
</ListBox>
It is also possible to achieve this functionality via an attached property, as I described it on my blog. The idea is to register the ApplicationCommands.Copy command with the ListView and, when the command is executed, read the values from the data bindings.
You'll find a downloadable sample on the blog entry, too.

Resources