How to switch ribbon tab programmatically? - wpf

I have a ribbon in my view named 'ribbon' that have 2 tabs as below sample codes. I want Button1 when clicked will open Tab2 and vice versa. How would I do this?
<ribbon:Ribbon x:Name="ribbon" HelpPaneContent="{x:Static data:WordModel.Help}">
<ribbon:RibbonTab Header="Tab1" ... >
<ribbon:RibbonGroup x:Name="Button1" >
<ribbon:RibbonButton Clicked="SwitchToTab2" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
<ribbon:RibbonTab Header="Tab2" ... >
<ribbon:RibbonGroup x:Name="Button2" >
<ribbon:RibbonButton Clicked="SwitchToTab1" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
...
</ribbon:Ribbon>

You only have to trigger the IsSelected property of your tabs
private void SwitchToTab1(object sender, MouseButtonEventArgs e)
{
ribbontab1.IsSelected = true;
}
private void SwitchToTab2(object sender, MouseButtonEventArgs e)
{
ribbontab2.IsSelected = true;
}

Found myself: If your ribbon control named 'Ribbon' then call this in your button's clicked handler:
Ribbon.SelectedIndex = indexOfTab;
Hope that would help anyone with the same problem with me.

Simple, using:
ribbonName.Tabs[TabNumber].IsSelected=true;

I my opinion that is purely layout related stuff so I would attach an eventhandler to the buttons to change the SelectedTab.

Related

WPF UserControl generic click event

I have created a UserControl in WPF which consists of 2 simple buttons in the first run.
Now, I want to display in a MessageBox the x:Name of the button which is clicked by the user, but I don't want to create a Clicked event for each button separately.
Is it possible to program 1 generic Clicked event in the UserControl and then identify the sender object to get the correct x:Name ?
Is it possible to program 1 generic Clicked event in the UserControl and then identify the sender object to get the correct x:Name ?
Sure:
<Button x:Name="first" Click="generic_Click" />
<Button x:Name="second" Click="generic_Click" />
private void generic_Click(object sender, RoutedEventArgs e)
{
Button clickedButton = sender as Button;
MessageBox.Show(clickedButton.Name);
}
Use an EventSetter for that in a style for a button.
Example in xaml:
<StackPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.EventOvw2"
Name="dpanel2"
Initialized="PrimeHandledToo"
>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}">
<EventSetter Event="Click" Handler="b1SetColor"/>
</Style>
</StackPanel.Resources>
<Button>Click me</Button>
<Button Name="ThisButton" Click="HandleThis">
Raise event, handle it, use handled=true handler to get it anyway.
</Button>
</StackPanel>
And then in cs file:
void b1SetColor(object sender, RoutedEventArgs e)
{
Button b = e.Source as Button;
b.Background = new SolidColorBrush(Colors.Azure);
}
void HandleThis(object sender, RoutedEventArgs e)
{
e.Handled=true;
}

Click Button under Border in wp8.1

Is it possible to click Button which is covered by Border?
If it is, how to handle occurred events?
This is page layout:
<Page x:Class="App6.MainPage"
<!-- ... -->
>
<Grid>
<Button Content="click" />
<Border Background="Transparent" />
</Grid>
</Page>
The main idea is to catch gesture manipulations (with Border) but also allow using controls.
Thanks in advance for any help.
Thanks to this I found the way to solve this issue.
Just need to add handler and set parameter handledEventsToo in true:
public MainPage()
{
this.InitializeComponent();
this.Button.AddHandler(PointerPressedEvent, new PointerEventHandler(pointerPressedEvent), true);
}
private void pointerPressedEvent(object sender, PointerRoutedEventArgs e)
{
}
After that you can see UI callback after clicking the button

RibbonSplitButton click event

Gentelman,
I'm binding a collection to RibbonSplitButton (basically, showing 3 values: red, green, blue) Everything works fine except of the problem I have to figure out which color (item) has been chosen:
Here's my code:
<r:RibbonSplitButton Name="TagEm"
LargeImageSource="Images\pencil_32.png"
Label="Tag"
ItemsSource="{Binding Path=TagCollection}"
Click="TagEm_Click">
<r:RibbonSplitButton.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Descr}" />
</DataTemplate>
</r:RibbonSplitButton.ItemTemplate>
</r:RibbonSplitButton>
Code behind:
private void TagEm_Click(object sender, RoutedEventArgs e)
{
}
Something like (Tag)TagEm.Items.CurrentItem;
Could someone give me a hint, please?
Many thanks in advance!
N.
Do not use the RibbonSplitButton Click event. Instead use the TextBox MouseLeftButtonUp event.
XAML:
<r:RibbonSplitButton
Name="TagEm"
LargeImageSource="Images\pencil_32.png"
Label="Tag"
ItemsSource="{Binding Path=TagCollection}">
<r:RibbonSplitButton.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" MouseLeftButtonUp="TextBlock_MouseLeftButtonUp" />
</DataTemplate>
</r:RibbonSplitButton.ItemTemplate>
</r:RibbonSplitButton>
Event Handler:
private void TextBlock_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Tag clickedTag = (sender as TextBlock).DataContext as Tag;
}

Is there a way to programatically close a menuitem in WPF

I have a menu in wpf that has an input box and a button on it. Once the user clicks the button I need to close the menu.
Is there a way to do this?
<Menu x:Name="MainMenu">
<MenuItem Header="Main">
<MenuItem Header="SubMenu" x:Name="SubMenu">
<StackPanel Orientation="Horizontal">
<TextBox Width="50" x:Name="TextBox" />
<Button Content="Click Me and Close" x:Name="Button" IsDefault="True"/>
</StackPanel>
</MenuItem>
</MenuItem>
Thanks,
Jon
Get hold of the MenuItem and do:
_menuItem.IsSubmenuOpen = false;
Easy way to get hold of it:
<Button x:Name="_button" Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}, AncestorLevel=2}"/>
Code-behind:
_button.Click += delegate
{
(_button.Tag as MenuItem).IsSubmenuOpen = false;
};
I find that using IsSubmenuOpen doesn't properly eliminate focus from the Menu containing the MenuItem (especially if the Menu is in a ToolBar - the top-level MenuItem remains Selected even though the menu is "Closed"). I find sending a MouseUp event to the MenuItem works better (in the button's, or nested control's, Click event handler):
private void button_Click(object sender, RoutedEventArgs e) {
Button b = sender as Button;
if (b == null || !(b.Parent is MenuItem))
return;
MenuItem mi = b.Parent as MenuItem;
mi.RaiseEvent(
new MouseButtonEventArgs(
Mouse.PrimaryDevice, 0, MouseButton.Left
)
{RoutedEvent=Mouse.MouseUpEvent}
);
}
Steve thanks for your solution. That is actually right answer, and finally something that really works beside of tons of bad answers over the internet. I have a shorter (and more safe) solution based on your anwser. Because direct parent (e.Parent) of the button is not always MenuItem (from original answer that is StackPanel), your solution will not work. So just set the Name property of the MenuItem (Name="MyMenuItem") and hook this handler on the Button:
private void Button_Click(object sender, RoutedEventArgs e) {
MyMenuItem.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) {
RoutedEvent = Mouse.MouseUpEvent
});
}

Is faking a WPF mouseover possible?

I have a data template with a textbox and a button with some styles on it. I would like to have the button show the mouse over state when focus is on the textbox beside it. Is this possible?
I figure it would involve something like this. I can get the textbox through use of FindVisualChild and FindName. Then I can set the GotFocus event on the textbox to do something.
_myTextBox.GotFocus += new RoutedEventHandler(TB_GotFocus);
Here in TB_GotFocus I'm stuck. I can get the button I want to show the mouse over state of, but I don't know what event to send to it. MouseEnterEvent isn't allowed.
void TB_GotFocus(object sender, RoutedEventArgs e)
{
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(this.DataTemplateInstance);
DataTemplate template = myContentPresenter.ContentTemplate;
Button _button= template.FindName("TemplateButton", myContentPresenter) as Button;
_button.RaiseEvent(new RoutedEventArgs(Button.MouseEnterEvent));
}
I don't think it's possible to fake the event but you can force the button to render itself as if it had MouseOver.
private void tb_GotFocus(object sender, RoutedEventArgs e)
{
// ButtonChrome is the first child of button
DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
chrome.SetValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty, true);
}
private void tb_LostFocus(object sender, RoutedEventArgs e)
{
// ButtonChrome is the first child of button
DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
chrome.ClearValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty);
}
you need to reference PresentationFramework.Aero.dlll for this to work and then it will only work on Vista for the Aero theme.
If you want it to work for other themes you should make a custom controltemplate for each of the theme you want to support.
See http://blogs.msdn.com/llobo/archive/2006/07/12/663653.aspx for tips
As a follow up to jesperll's comment, I think you can get around making a custom template for each theme by dynamically setting the style to the one you want / null.
Here is my window, with the style defined (but not set to anything).
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="MouseOverStyle">
<Setter Property="Background">
<Setter.Value>Green</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="MyTextBox" Grid.Column="0" Text="Some Text" Margin="2" GotFocus="TextBox_GotFocus" LostFocus="MyTextBox_LostFocus"/>
<Button x:Name="MyButton" Grid.Column="1" Content="Button" Margin="2" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" />
</Grid>
Instead of setting the style via triggers in the template, you can use events in your .cs file like so:
...
public partial class Window1 : Window
{
Style mouseOverStyle;
public Window1()
{
InitializeComponent();
mouseOverStyle = (Style)FindResource("MouseOverStyle");
}
private void TextBox_GotFocus(object sender, RoutedEventArgs e) { MyButton.Style = mouseOverStyle; }
private void MyTextBox_LostFocus(object sender, RoutedEventArgs e) { MyButton.Style = null; }
private void Button_MouseEnter(object sender, MouseEventArgs e) { ((Button)sender).Style = mouseOverStyle; }
private void Button_MouseLeave(object sender, MouseEventArgs e) { ((Button)sender).Style = null; }
}
You get a reference to the style in the constructor and then dynamically set it / unset it. This way, you can define what you want your style to look like in Xaml, and you don't have to rely on any new dependencies.

Resources