RibbonControl: center Title - wpf

I'm using the Microsoft RibbonControl on a UserControl (it needs to be so we can host it on a stub form to host the WPF in our MDI system). Sadly, the title of the Ribbon displays Top/Left in the ribbon's header, and it looks ridiculous. How do I get at that sucker?

I am working on just about the same thing right now. I solved it by using a datatemplate for the ribbon title:
<r:Ribbon.TitleTemplate>
<DataTemplate>
<TextBlock Text="Put you title here" Margin="3,3,0,0"></TextBlock>
</DataTemplate>
</r:Ribbon.TitleTemplate>
If the ribbon is used in a RibbonWindow, you probably also want to add a glow to the title text to be able to read it properly when placed over a dark background. In that case, add this XAML inside the TextBlock:
<TextBlock.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="White" Opacity="0.7" GlowSize="10"/>
</TextBlock.BitmapEffect>
There is one more problem with the Ribbon when used within a RibbonWindow; the title text will either be placed correctly when window state is Normal or when window is maximized. To solve this I bound the TextBlock Margin to a property in the codebind:
public Thickness TitleMargin
{
get { return this.WindowState == WindowState.Maximized ? new Thickness(0, 3, 0, 0) : new Thickness(0); }
}
To get this working, you also need to fire a PropertyChanged event each time the window state changes:
protected override void OnStateChanged(EventArgs e)
{
OnPropertyChanged("TitleMargin");
base.OnStateChanged(e);
}

Related

WPF: binding elements in main window and user control

I am new to WPF and MVVM and not sure how to solve this (probbaly simple) problem. I have a MainWindow with two regions: RibbonView and below it a TabControl (Telerik). I have big buttons in the ribbon control which are always enabled. For example, I have a button "Tenants" and when I click on this button I create a new tab item and place my TenantControl containing a GridView control (also from Telerik). Its content is automatically loaded.
Now I want to get the following to work: additionally I have some small buttons (Add, Delete, Clone etc) (Ribbon control) that are disabled by default and I want to enable these buttons when I select an item in a grid. Is the using of routed commands the proper way to solve the problem? How to enable a button in a main window if I select an item in a grid in own user control? And yes in a main window I have a reference to the user control. No need for code just a concept is needed - as I said before I am completelly new to WPF/MVVM.
Thanks for any help and best regards,
Erno
In my WPF Applications, I often use RibbonBars as well, but instead of creating different TabItems for the different views, I display them all in one place by using a ContentControl and then just changing the Content value to different view models which are then rendered as the relevant views:
In Mainview:
<ContentControl Content="{Binding ViewModel}" />
...
In MainViewModel:
ViewModel = new SomethingViewModel();
...
In App.xaml:
<DataTemplate DataType="{x:Type ViewModels:SomethingViewModel}">
<Views:SomethingView />
</DataTemplate>
In my MainViewModel class, I have a helper method:
private bool IsViewModelOfType<T>()
{
return ViewModel != null && ViewModel.GetType() == typeof(T);
}
This method is used in the ICommand.CanExecute property to enable and disable Commands dependant on the loaded view model:
public ICommand CopyTrackList
{
get { return new ActionCommand(action => ClipboardManager.SetClipboardText(
((ReleaseLabelCopyViewModel)ViewModel).TrackList), canExecute =>
IsViewModelOfType<ReleaseLabelCopyViewModel>() &&
((ReleaseLabelCopyViewModel)ViewModel).SomePropertyInChildViewModel == true); }
}

WPF ViewModel overriding values set declaratively in XAML

I have the following user control:
<HMIClasses:vhMotor x:Name="vhDevice"
AutoSize="{Binding AutoSize,Mode=TwoWay}"
DeviceColour="{Binding DeviceColour,Mode=TwoWay}"
MotorOn="{Binding MotorOn,Mode=TwoWay}"
DeviceSize="{Binding DeviceSize,Mode=TwoWay}"
LayoutDirection="{Binding LayoutDirection,Mode=TwoWay}"
Speed="{Binding Speed,Mode=TwoWay}"
HorizontalAlignment="{Binding HorizontalAlignment,Mode=TwoWay}"
VerticalAlignment="{Binding VerticalAlignment,Mode=TwoWay}"
Margin="{Binding Margin,Mode=TwoWay}" >
This is bound to the datacontext of the (this) user control here:
public ucMotor() : base()
{
Initialise();
InitializeComponent();
this.DataContext = CreateViewModel()
}
When I place the user control in XAML, the DependenyProperties are only applied when I edit them. What I mean is, if I declare the user control and specify properties as such:
<local:ucMotor x:Name="motor1"
DeviceColour="Red"
MotorOn="True"
Speed="Superspeed"
....Sure enough the control responds to the changes within the designer.
If I close and reopen form, the control appears with the properties of the view model and does not reflect those of the XAML. For example, the view model's default colour is silver and the control appears in silver despite the XAM specifying red.If I edit the XAML, the user control is refreshed in the correct colour.
This is my first attempt at user controls and dependency properties, so can someone please tell me where I'm going wrong?
Thanks

How change color from control page in panorama page using coding4fun color picker

Hi. I use this ColorPicker. I have first control page (Popup) and second main page(panorama page). Now I want pickup color via ColorPicker in control page and set brush color etc for some element (for example grid background color) in main page. But I dont know how I can bind color from control page to main page (panorama page). Any idea or link for example, Thx.
In control Popup .xaml I have:
<c4fToolkit:ColorPicker x:Name="picker" Height="180" Width="450" ColorChanged="picker_ColorChanged" />
In control Popup.cs I have:
public Brush myColor { get; set; }
public MondayPopup()
{
InitializeComponent();
DataContext = this;
}
private void picker_ColorChanged(object sender, Color color)
{
? = new SolidColorBrush(color);
}
In main page .xaml I have
<Grid x:Name="gridColor" Background="{Binding myColor}" />
In main page .cs I havent nofhing because I dont know how bing color from control page via picker and save it(bind) to panorama main page and change color.
I haven't worked with the color picker yet but from what I know of these controls, you could try the Value property of the color picker. Thebn when you navigate to main page, use that Value and pass it to MainPage as a paramater.
NavigationService.Navigate(new Uri("/MainPage.xaml?Color="+colorPicker.Value.ToString(), UriKind.Relative));
Edit:
You also have a Color parmater in picker_ColorChanged. You could also pass that paramater back to MainPage.xaml.

Removing a UserControl added at runtime using a button within UserControl

I have seen a few posts addressing how to remove an UserControl that has been added during runtime, but my problem is a little different. I have a UserControl that consists of an image with a small "x" button on the top right corner that is used to remove itself (the UserControl) from its parent canvas. Also to note is that the UserControl is added during runtime when the user doubleclicks on a ListboxItem. I have a Click event handler for the top right corner button but this code is not running at all. I know this because I have a breakpoint in this code which is not reached when I click the button.
So,
Why isn't the click event of the remove button being handled?
Maybe there is a better way to implement this. Please advise.
Here's the code used for adding it:
private void MyListBox_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.OriginalSource.ToString() == "System.Windows.Controls.Border" || e.OriginalSource.ToString() == "System.Windows.Controls.Image" || e.OriginalSource.ToString() == "System.Windows.Controls.TextBlock")
{
Expression.Blend.SampleData.MyCollection.Dataset lbi = ((sender as ListBox).SelectedItem as Expression.Blend.SampleData.MyCollection.Dataset);
var new_usercontrol = new MyUserControl();
new_usercontrol.MyImageSourceProperty = lbi.Image;
MyCanvas.Children.Add(new_usercontrol);
Canvas.SetLeft(new_usercontrol, 100);
Canvas.SetTop(new_usercontrol, 100);
Canvas.SetZIndex(new_usercontrol, 100);
}
}
The following is the cs code for the UserControl:
public partial class ModuleElement : UserControl
{
public ImageSource MyProperty
{
get { return (ImageSource)this.image.Source; }
set { this.image.Source = value; }
}
public ModuleElement()
{
this.InitializeComponent();
}
private void RemoveButton_Click(object sender, RoutedEventArgs e)
{
((Canvas)this.Parent).Children.Remove(this);
}
}
The XAML:
<Grid x:Name="LayoutRoot">
<Image x:Name="image" />
<Button x:Name="RemoveButton" Content="X" HorizontalAlignment="Right" Height="17.834" Margin="0" VerticalAlignment="Top" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Click="RemoveButton_Click">
</Button>
</Grid>
Thanks in advance,
Bryan
So I tried your code here exactly except for some name changes and could not reproduce your issue. In my personal experience your issue here has to be that for some reason the event for the click isn't subscribed to properly. For this I would go into designer for the user control, wipe out the current event for the button and double click in the designer event textbox such that VS or Blend generates all the code necessary for a proper subscription.
I have created a sample based on your code here. Feel free to pull it down and take a look to see if you can find any inconsistencies.
As far as a better way to implement this, check out the good old MVVM pattern and the MVVM Light Toolkit. With this you can have a central ViewModel class that will handle all of your button commands and binding without code behind.

WPF Popup focus in data grid

I'm creating a custom UserControl to be used inside a DataGrid editing template.
It looks like this:
<UserControl
x:Class="HR.Controls.UserPicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock x:Name="PART_TextBox" Text="Hello WOrld" />
<Popup Width="234" Height="175" IsOpen="True" StaysOpen="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_TextBox}"
>
<TextBox
x:Name="searchTextBox"
Text=">Enter Name<"/>
</Popup>
</Grid>
</UserControl>
edit:
I've narrowed down the code a bit.
It seems that if I put a Popup with textbox inside the CellEditingTemplate directly the textbox gets focus no problem. When I move that code into a UserControl I can no longer select the textbox when editing the cell.
Is the UserControl doing something funny with the focus ?
The problem is when i edit the cell in the datagrid I get the user control showing up but I can't click in the TextBox searchTextBox. When I click on it the popup closes and the cell goes back to default.
I have tried copying and pasting all the code inside the user control and pasting it directly into the CellEditingTemplate and that interacts the way it should.
I was just wondering if the UserControl did something weird that prevents a popup from gaining focus because it works as expected when directly placed in the CellEditingTemplate ?
Thanks,
Raul
Not sure if this will help anyone, but this helps if you have custom controls in the datagrid with a popup..... this fixed my problem, and it was one line of xaml. I spend the whole day re-reading this forum and then looking at the source for DataGridCell. Hope this helps.
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Focusable" Value="False"></Setter>
</Style>
I had a similar problem where a Popup embedded in a UserControl as a cell editing template would close when certain areas of it were clicked. The problem turned out to be that the WPF Toolkit (and presumably WPF4) DataGrid is very greedy with left mouse clicks. Even when you handle them and set Handled to true, the grid can interpret them as clicking into a different cell.
This thread has the full details, but the fix is to hook into DataGrid.CellEditEnding event and cancel the end edit:
private static void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (e.Column.GetType() == typeof(DataGridTemplateColumn))
{
var popup = GetVisualChild<Popup>(e.EditingElement);
if (popup != null && popup.IsOpen)
{
e.Cancel = true;
}
}
}
private static T GetVisualChild<T>(DependencyObject visual)
where T : DependencyObject
{
if (visual == null)
return null;
var count = VisualTreeHelper.GetChildrenCount(visual);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(visual, i);
var childOfTypeT = child as T ?? GetVisualChild<T>(child);
if (childOfTypeT != null)
return childOfTypeT;
}
return null;
}
Full credit for this goes to the Actipro thread.
Set FocusManager.IsFocusScope Attached Property on the Popup to True
I had a kinda simular problem, i created a usercontrol containing a textbox, a button and a calendar. Basicaly i create my own datepicker with custom validation logic.
I put this component in a CellEditingTemplate. When i pressed the button, the popup showed, but clicking the popup anywhere caused the cell te stop editing (because the popup was taking focus from the textbox). I solved it by adding code that sais that if the popup is open, the focus of the textbox may not be lost. This did the trick for me.
Also, the in the on loaded event handler of the usercontrol i give focus to the textbox.
In your case it's propably the Usercontrol itsefl that has focus.
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) {
// Don't allow focus to leave the textbox if the popup is open
if (Popup.IsOpen) e.Handled = true;
}
private void Root_Loaded(object sender, RoutedEventArgs e) {
TextBox.Focus();
}

Resources