Hi Mike,
My intention is to select the Tab when the CommandParameter (which is a CheckableCommandParameter) IsChecked property is true. In other words, the CommandParameter tells to the Tab to select itself.
I'll present my solution below.
I've implemented 2 classes. The first is CustomCheckableCommandParameter. This class extends ICheckableCommandParameter. The difference between built-in CheckableCommandParameter class and CustomCheckableCommandParameter is that the last one announces when IsChecked property changes. See the code below.
public class CustomCheckableCommandParameter : DependencyObject, ICheckableCommandParameter
{
#region Fields
public static readonly DependencyProperty IsCheckedProperty;
public static readonly DependencyProperty HandledProperty;
public static readonly DependencyProperty TagProperty;
#endregion Fields
#region Properties
public bool? IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
public bool Handled
{
get { return (bool)GetValue(HandledProperty); }
set { SetValue(HandledProperty, value); }
}
public object Tag
{
get { return (object)GetValue(TagProperty); }
set { SetValue(TagProperty, value); }
}
#endregion Properties
#region Events
public event EventHandler IsCheckedChanged;
#endregion Events
static CustomCheckableCommandParameter()
{
IsCheckedProperty =
DependencyProperty.Register(
"IsChecked",
typeof(bool),
typeof(CustomCheckableCommandParameter),
new PropertyMetadata(false, new PropertyChangedCallback(OnCheckedChanged)));
HandledProperty =
DependencyProperty.Register(
"Handled",
typeof(bool),
typeof(CustomCheckableCommandParameter),
new PropertyMetadata(false));
TagProperty =
DependencyProperty.Register(
"Tag",
typeof(object),
typeof(CustomCheckableCommandParameter),
new PropertyMetadata((object)null));
}
public CustomCheckableCommandParameter()
: base()
{
}
private static void OnCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CustomCheckableCommandParameter checkableParameter = (CustomCheckableCommandParameter)d;
checkableParameter.OnIsCheckedChanged();
}
protected virtual void OnIsCheckedChanged()
{
if (IsCheckedChanged != null)
{
IsCheckedChanged(this, EventArgs.Empty);
}
}
}
The second class that I've implemented is CustomRibbonTab. It extends the ActiproSoftware.Windows.Controls.Ribbon.Controls.Tab class. See code below.
public class CustomRibbonTab : ActiproSoftware.Windows.Controls.Ribbon.Controls.Tab
{
public CustomRibbonTab()
: base()
{
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (e.Property == CommandParameterProperty)
{
HookUpIsChecked();
}
base.OnPropertyChanged(e);
}
private void HookUpIsChecked()
{
var param = CommandParameter as CustomCheckableCommandParameter;
if (null != param)
{
param.IsCheckedChanged += delegate
{
if (param.IsChecked == true)
{
var ribbon = UIHelper.FindAncestor(this, typeof(Ribbon)) as Ribbon;
if (null != ribbon)
{
ribbon.SelectedTab = this; //in this way I'm selecting the right tab
//this.IsChecked = true; // this line doesn't select the right tab
}
}
};
}
}
}
Having these 2 classes the XAML code will look this way:
<!-- "Suppliers" Tab -->
<p:CustomRibbonTab Label="Suppliers" Command="NavigationCommands.GoToPage" CommandTarget="{Binding ElementName=local, Path=TargetContentContainer}">
<p:CustomRibbonTab.CommandParameter>
<p:CustomCheckableCommandParameter Tag="{x:Type p:SuppliersListPage}"/>
</p:CustomRibbonTab.CommandParameter>
</p:CustomRibbonTab>
The solution I presented does what I expect, logically speaking. But the visual result is unexpected.
The line of code
ribbon.SelectedTab = this
produces a translation to the left of the ribbon tabs.
Any idea will be welcome.
Thanks.
Mark