How to add a focus style to an editable ComboBox in WPF - wpf

I've been looking at the following example on how to style the ComboBox, but I haven't been able to create a focus effect when going into an editable combo box. Whenever the ComboBox receives focus, it should go into edit mode and the component should have a focus style.
The basic problem is that whenever I go into the edit mode, it's not the surrounding ComboBox which actually has the focus, but the text subcomponent and I haven't been able to create a Trigger on the text component which modifies the ComboBox's border style since I don't know how to refer to the parent component from the trigger.
I've tried adding ControlTemplate Trigger on the TextBox, or style trigger. I've tried to refer to the ComboBox by name or by using the TemplateBinding option, but without any luck. A simple example would be very appreciated.

Bind IsKeyboardFocusWithin to IsDropDownOpen
<ComboBox ItemsSource="{Binding SortedItems}"
StaysOpenOnEdit="True"
IsDropDownOpen="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}, Mode=OneWay}" />

private void cmbSpecialHandling_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_LostFocus(object sender, RoutedEventArgs e)
{
cmbSpecialHandling.BorderBrush = Brushes.Transparent;
}

Set the border brush of combobox in its Gotfocus and make it transparent in lost focus:
private void comboBox_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
comboBox.BorderThickness = th;
comboBox.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
or
comboBox.BorderBrush = Brushes.Green;
}
private void comboBox_LostFocus(object sender, RoutedEventArgs e)
{
comboBox.BorderBrush = Brushes.Transparent;
}

Related

Problem with same Blend behaviour applied to multiple elements

I created a simple Blend behaviour to be attached to TextBox elements. It's purpose is to scroll the textbox to its end when it gets the focus, and to scroll it back to the beginning when it loses the focus.
public class TextBoxScrollToEndBehaviour : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.GotFocus += AssociatedObject_GotFocus;
AssociatedObject.LostFocus += AssociatedObject_LostFocus;
}
private void AssociatedObject_LostFocus(object sender, System.Windows.RoutedEventArgs e)
{
var textBox = sender as TextBox;
textBox.ScrollToHorizontalOffset(0);
}
private void AssociatedObject_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
var textBox = sender as TextBox;
textBox.ScrollToHorizontalOffset(double.PositiveInfinity);
}
}
Xaml:
<TextBox Text="{Binding MyBinding, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Behaviors>
<behaviours:TextBoxScrollToEndBehaviour />
</i:Interaction.Behaviors>
</TextBox>
It works great when I focus the TextBox and then I click on some other control to loose the focus. Problem is that if I switch the focus between two TextBox that share the same behaviour, the scroll is not set back to 0 on the first TextBox, even the LostFocus event is correctly triggered on it.
What am I missing here? Thanks!
.NET Framework 4.7.2
I found out that by replacing this line in the LostFocus event:
textBox.ScrollToHorizontalOffset(0);
with
textBox.ScrollToLine(0);
the behaviour works perfectly in any condition.

Keep submenu open when a new image is selected for display

Using WPF: A Simple Color Picker With Preview, Sacha Barber, 18 Apr 2012 ,
I created a custom control from it:
public class ColorCustomControl : Control
{....}
It is then used as:
<Menu....>
<MenuItem.....>
<pn:ColorCustomControl/>
</MenuItem>
</Menu>
This yields the following picture when the Brushes MenuItem is selected:
Selection of any item in the opened Brushes submenu results in the appropriate action being taken with the Brushes submenu REMAINING OPEN. This is the effect I want.
However, as shown below, selection of any of the three swatches results in a quick flicker of the new swatch -- it replaces the color pattern to the left of "Preview"--followed immediately by closure of the Brushes submenu.
If the Brushes menuitem is again chosen, the most recently selected swatch correctly appears.
I have tried all preview events (i.e., keyboard lost focus, left mouse down, etc.), to try stopping closure of the submenu when a swatch is chosen. Nothing I have found will stop the popup from closing.
How can closure of the Brushes submenu be prevented when selecting a swatch from the visual?
(I strongly suspect that redrawing of the visual, as in InvalidateVisual() when a new swatch image is selected, is forcing closure of the submenu).
Any ideas anybody?
TIA
My suggestion is to stop events propagation from your user control. So in your ColorCustomControl class first of all add a property (it can be a dependency one too if you need):
private bool propagateEvents = true;
public bool PropagateEvents
{
get
{
return propagateEvents;
}
set
{
propagateEvents = value;
}
}
Then add e.Handled = !PropagateEvents; at the end of every mouse event handler; in the end add a Swatch_MouseLeftButtonUp method (it has to handle the event raised by ImgSqaure1, ImgSqaure2 and ImgCircle1).
The result will be:
private void Swatch_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Image img = (sender as Image);
ColorImage.Source = img.Source;
e.Handled = !PropagateEvents;
}
private void Swatch_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
e.Handled = !PropagateEvents;
}
private void CanvImage_MouseDown(object sender, MouseButtonEventArgs e)
{
IsMouseDown = true;
e.Handled = !PropagateEvents;
}
private void CanvImage_MouseUp(object sender, MouseButtonEventArgs e)
{
IsMouseDown = false;
e.Handled = !PropagateEvents;
}
and in the user control XAML:
<Image x:Name="ImgSqaure1"
Height="20" Width="20"
Source="Images/ColorSwatchSquare1.png"
Margin="45,0,0,0"
ToolTip="Square swatch1"
MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
MouseLeftButtonUp="Swatch_MouseLeftButtonUp"/>
<Image x:Name="ImgSqaure2"
Height="20" Width="20"
Source="Images/ColorSwatchSquare2.png" Margin="5,0,0,0"
ToolTip="Square swatch2"
MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
MouseLeftButtonUp="Swatch_MouseLeftButtonUp"/>
<Image x:Name="ImgCircle1" Height="20" Width="20"
Source="Images/ColorSwatchCircle.png" Margin="5,0,0,0"
ToolTip="Circle swatch1"
MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
MouseLeftButtonUp="Swatch_MouseLeftButtonUp" />
Now all you have to do is set the PropagateEvents property in your menu:
<Menu....>
<MenuItem.....>
<pn:ColorCustomControl PropagateEvents="False" />
</MenuItem>
</Menu>
I hope it can help you.

Getting Listbox Item Index from Button Click

So I'm using a button in the DataTemplate of my Listbox ItemTemplate. Any ideas how I would grab the index of the item of the Listbox from the button click? I can't see to grab the button's parent.
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Img}">
<Button Click="lstButton_Click">...
private void lstButton_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
int index = _myListBoxName.Items.IndexOf(button.DataContext);
//or try this
index = _myListBoxName.ItemContainerGenerator.IndexFromContainer(button.DataContext);
}
You could add a Index property in your view model and set it when you add the view model object into your collection. And then you can access it in your event handler.
private void lstButton_Click(object sender, RoutedEventArgs e)
{
Img t = (sender as Button).DataContext as Img
//Access t.Index here
}

Change background color of HyperLinkButton on MouseOver/MouseEnter in Silverlight

I am new to silverlight,will any one guide how can I do this.
Thanx
XAML:
<HyperlinkButton Name="hyperlinkButton" Content="Change Background" MouseEnter="hyperlinkButton_MouseEnter" MouseLeave="hyperlinkButton_MouseLeave" />
Code Behind:
private void hyperlinkButton_MouseEnter(object sender, MouseEventArgs e)
{
hyperlinkButton.Background = new SolidColorBrush(Colors.Red);
}
private void hyperlinkButton_MouseLeave(object sender, MouseEventArgs e)
{
hyperlinkButton.Background = new SolidColorBrush(Colors.White);
}
Here is video tutorial "How to Style a Hyperlink Button". There you can see
How to change the color of a Hyperlink Button when the mouse is over it.
Source code for download is also available.
If you whant to do that as #BurkDigglers described, than you must handle MouseEnter and MouseLeave events for each hyperlink button.

Focus the controls in a Tabcontrol

How can focus the controls when select a tabitem in a tabcontrol?
You should capture the Selection changed event of the TabControl and inside that you focus the control you need. Just as
private void TabControl1_SelectionChanged(object sender, EventArgs e)
{
control1.Focus();
}
Not sure I understand what you're asking completely, but you probably want to capture the SelectionChanged event for the TabControl:
public Window1()
{
InitializeComponent();
TabControl1.SelectionChanged += TabControl1_SelectionChanged;
}
private void TabControl1_SelectionChanged(object sender, EventArgs e)
{
TabItem item = (TabItem)TabControl1.SelectedItem;
// Find the first control in the TabItem content and focus it?
}

Resources