How do i make listbox items not selectable? [duplicate] - c#

I have a listbox in WPF, and when they select an item, it shows an ugly colors
Can I make all the items non-selectable?

If you don't need selection, use an ItemsControl rather than a ListBox

Add Focusable property as false in ListBoxItem style:
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
<!-- Possibly other setters -->
<Setter Property="Focusable" Value="False" />
</Style>

Please use this inside your listbox. I found this very elegant solution
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

If you dont want them selectable then you probably dont want a listview.
But if this is what you really need then you can do it with a style:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="#DDDDDD"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid>
<ListBox>
<ListBoxItem>One</ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
<ListBoxItem>Three</ListBoxItem>
</ListBox>
</Grid>
</Page>
Look at the IsSelected Trigger. You can make the border a different colour so it is not "Ugly" or set it to transparent and it will not be visible when selected.
Hope this helps.

There's an even easier way: set ListBox property IsHitTestVisible="False". This prevents all the items in the list from receiving mouse events. This has the advantage of stopping the highlighting as you mouse-over as well.
It works for me in WP 7.1.

A simple way to do this (using the answer from viky above) is to set the selected index to -1 in the SelectionChanged(), as follows.
public void OnListView_SelectionChanged(Object sender, RoutedEventArgs e)
{
if (null != sender && sender is ListView)
{
ListView lv = sender as ListView;
lv.SelectedIndex = -1;
}
}

Better to avoid events, it's more elegant and without side effects the Style tag.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
... what you want as a source ...
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

you can handle SelectionChanged event of ListBox and unselect the selected item in the event handler.

You can also make disabled Listbox, which will give you static, non-interactive listbox.
<ListBox IsEnabled="False"/>
I think this is the solution as simple as possible.

In my case I had templated ListboxItems with a Textblock and a ComboBox. The only "active" should be the Combo...
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
CanContentScroll="True" />
<ItemsControl>
....here my content....
</Itemscontrol>
</ScrollViewer>
did work for me as expected.
BR,
Daniel

You can also handle PreviewMouseDown event
And to prevent tap you can set KeyboardNavigation.TabNavigation="None"
<ListView x:Name="Cards"
.....
PreviewMouseDown="CardMonthsDescriptors_OnPreviewMouseDown"
KeyboardNavigation.TabNavigation="None"
>
...
private void Cards_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}

Related

Selecting a partially displayed WPF checkbox

I am having a design problem and I know there has to be a way to make it work. I tried the solutions here: Annoying auto scroll of partially displayed items in WPF ListView
But they didnt work for me because I am not allowed to work in the code-behind.
I have a list of items from a wpf ListBox. like this:
when I try to select the CheckBox in line 5, the Window centers on it but does not check it. After further testing, I found that it will not select the CheckBox as long as the bottom border of the item is not in view.
Here is the xaml for the ListBox and its Style:
<ListBox Grid.Column="0" Grid.Row="1" Name="RequestCheckoutV"
ItemsSource="{Binding Path=CheckoutVM, Mode=TwoWay, IsAsync=True}"
SelectedItem="{Binding Path=SelectedPermit}"
BorderThickness="0"
KeyboardNavigation.TabNavigation="Continue">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Control.HorizontalContentAlignment" Value="Center"/>
<Setter Property="Control.VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
What can I do to make this select the checkbox instead of just centering it?
Any help is appreciated.
So by adding the specification of "Press" to ClickMode property to CheckBox via ClickMode="Press" you're telling that object to basically ignore the event otherwise hijacked by the list item template. Now it will accept the first event in it's hit area for itself instead of the list item since it's default is "Release". Cheers :)
Try adding to your .ItemContainerStyle:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
This will effectively give focus to anything you click in there.

ContentControl switch between two buttons

I've been banging my head over this all night. All I want to do is have a content control that can switch between showing two different buttons according to a boolean in the ViewModel.
Basically I have a task running in the background with a cancel button. Once you hit cancel and the task stops, the cancel button should change to a back button. These are two separate button elements, not just changing a single button's properties. I'm using MahApps TransitioningContentControl so I want to be able to use the transitions.
I would be amazing if this could mostly be done all in XAML. I really don't want to have to add a bunch of boilerplate code for what should be a simple thing.
Edit: Here's the snippet of code. There isn't much because I just deleted everything that wasn't working.
<Controls:TransitioningContentControl x:Name="CancelBackButtonControl" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Height="80">
<Canvas>
<Button x:Name="CancelButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_close}" BorderBrush="Black" Command="{Binding CancelCommand}"/>
<Button x:Name="GoBackButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_arrow_left}" BorderBrush="Black" Command="{Binding GoBackCommand}"/>
</Canvas>
</Controls:TransitioningContentControl>
There are a staggering amount of ways to accomplish this (that's the beauty of WPF); however, in my personal opinion, you would be working less "against the grain" if you simply use a control that derives from the ToggleButton, such as RadioButton, especially since you want it to be done all in XAML. An important thing is not to think of any of the controls by their visuals, but by how they function. I've done some incredible things with RadioButton before, so that's the first thing I'll demonstrate; however, the regular button approach is included in the second half of this answer.
Here are the complete examples of both approaches (RadioButton and Button), done completely in XAML:
Preview:
Code:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type RadioButton}" x:Key="FlatRadioButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="Background" Value="#FF346FD6"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="5,2,5,3"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF6696E9"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<RadioButton x:Name="BackButton" Content="Back">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<RadioButton x:Name="CancelButton" Content="Cancel" IsChecked="True">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
</Grid>
</Window>
Most of the resource style code is visual styling and templating, focused on making radio buttons look like regular buttons, so it's not of great importance. The areas we'll focus on are Triggers. You'll notice that in the resource style, I ensure that when a RadioButton gets checked, it collapses. However, in the local style of each button, I ensure that when the other RadioButton gets checked, it makes the current RadioButton visible. This has to be done in the local style, since we need to pass the ElementName into the Binding. So, when a RadioButton gets checked, it collapses and makes the other RadioButton visible. You'll also note that I check the button I wish to hide by default. Obviously, you can wire that up with bindings.
Similar approaches may be applied to regular buttons:
Preview:
Code:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ToggleButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button x:Name="CancelButton" Content="Cancel">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button x:Name="BackButton" Content="Back">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
Here, instead of IsChecked, I'm working with IsFocused. You may accomplish a similar thing by working with the EventTrigger and Click event... but, there's more work. IsPressed may appear like a good candidate, but the problem is that once you press the button, the other one will appear almost instantaneously, and that one will have IsPressed set to true almost instantaneously. So, you'll end up with this cyclic behavior where it seems like nothing is happening. Note that I use Grid to place these buttons on top of each other, with the the one I want to be visible by default at the top, that way I don't have to worry about default visibility or focus. However, you may use any other panel, just set the Visibility of the button you want to hide by default to Collapsed.
If you don't want to work with multiple controls (two buttons in this case), you may also set the Content property of a button based on a condition through DataTrigger to display different text. You just have to ensure that you handle the Command appropriately.
Since you're asking for a XAML only way to switch the button in a content control based on a ViewModel property, how about this:
First define button style to route both buttons to the same event:
<Style x:Key="buttonClickButton" TargetType="Button">
<EventSetter Event="Click" Handler="Button_Click"/>
</Style>
Then define your content control style with a data trigger switching the content based on a ViewModel property called "IsCancelButton" (bool):
<Style x:Key="ButtonSwitchContentCtrl" TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding IsCancelButton}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Button x:Name="CancelButton" Style="{StaticResource buttonClickButton}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="80" Height="80" IsCancel="True" Content="Cancel Button" BorderBrush="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsCancelButton}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Button x:Name="GoBackButton" Style="{StaticResource buttonClickButton}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="80" Height="80" IsCancel="True" Content="Go Back Button" BorderBrush="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Then make your button(s) appear like so:
<ContentControl Style="{StaticResource ButtonSwitchContentCtrl}"/>
You can implement such functionality with just one Button (e.g. declared in XAML as Name="btnCancel") and simple code snippet in C# code-behind using Lambda-style event subscription like:
btnCancel.Click+=(s,e)=>{
if (btnCancel.Text=="Cancel")
{
// SOME CODE CORRESPONDING TO "CANCEL" CLICK EVENT
btnCancel.Text ="GoBack"
}
else
{
// CORRESPONDING TO "GoBack" CLICK EVENT
btnCancel.Text ="Cancel"
}
}
In case you want to use some graphic content (images) on the Button, then use Tag property of that Button instead of Text and also programmatically switch between images.
Couple other considerations: the business logic you have described could be implemented in XAML using DataTriggers (as other folks did), but instead of writing megaton of XAML for 2-Buttons solutions it would be reasonable to implement a single-button solution, either like this one, or using .NET ToggleButton Class (re: https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.togglebutton%28v=vs.110%29.aspx); also, it could be a CheckBox control just properly styled.
In any way, you most likely will need the event handlers to do some actual job in addition to just changing the visual state of the Button, so that compact Lambda-style event subscription would be handy.
Hope this may help. Best regards,

Changing WPF Listbox SelectedItem text color and highlight/background Color using C#

I am trying to change the highlighted(selected) color and the highlighted text color of a wpf listbox at runtime. I have tried creating a style and applying it as follows:
Style s = new Style(typeof(ListBox));
s.Resources.Add(SystemColors.HighlightBrushKey, Setting.ListSelectedColor);
s.Resources.Add(SystemColors.HighlightTextBrushKey, Setting.ListSelectedTextColor);
lstGames.Style = s;
But this seems to do nothing. Is there any way to achieve this?
EDIT:
Per suggestions, I tried using DynamicResources to achieve this, but so far this has not been successful either. My code for this:
DYNAMICRESOURCES
<UserControl.Resources>
<Color x:Key="ListTextSelectedColor"/>
<Color x:Key="ListSelectedColor"/>
</UserControl.Resources>
LISTBOX
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden"
Name="lstGames" Margin="20" Grid.Row="2" Grid.Column="2"
SelectionChanged="lstGames_SelectionChanged" Grid.RowSpan="2" Grid.ColumnSpan="2"
Background="{x:Null}" BorderBrush="{x:Null}" SelectionMode="Single"
FontSize="18" FontFamily="OCR A Extended">
<Style TargetType="ListBox">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource ListSelectedColor}"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{DynamicResource ListSelectedColor}"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="{DynamicResource ListTextSelectedColor}"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="{DynamicResource ListTextSelectedColor}"/>
</Style.Resources>
</Style>
</ListBox>
APPLYING RESOURCES IN C#
this.Resources["ListSelectedColor"] = SETING.ListSelectedColor.Color;
this.Resources["ListTextSelectedColor"] = SETTING.ListSelectedTextColor.Color;
Solution:
<Window x:Class="ListBoxStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:ListBoxStyle"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="_Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="_Border" Property="Background" Value="Yellow"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListBox ItemContainerStyle="{DynamicResource _ListBoxItemStyle}"
Width="200" Height="250"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>Hi</ListBoxItem>
</ListBox>
</Grid>
</Window>
Thanks to Vinkal and failedprogramming, I got everything working beautifully. I created the following Resources:
<UserControl.Resources>
<SolidColorBrush x:Key="ListTextSelectedColor" x:Shared="False"/>
<SolidColorBrush x:Key="ListSelectedColor" x:Shared="False"/>
<Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="_Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="_Border" Property="Background" Value="{DynamicResource ResourceKey=ListSelectedColor}"/>
<Setter Property="Foreground" Value="{DynamicResource ResourceKey=ListTextSelectedColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
And then applied the style to my listbox with:
ItemContainerStyle="{DynamicResource ResourceKey=_ListBoxItemStyle}"
And finally, change the solidcolorbrush resources (therefore changing the setter values) in my C# code by doing the following:
this.Resources["ListSelectedColor"] = EmulatorPage.ListSelectedColor;
this.Resources["ListTextSelectedColor"] = EmulatorPage.ListSelectedTextColor;
Thank you to both of you!
To all the neigh-sayers out there... do not lose hope! it can be done!
I started off with VSS right-click on the listbox and used every "Edit Template" and "Edit Additional Templates" for each thing available until I found the how these things work.
You start off quite simply with a list box, bound to MVVM as normal.
<ListBox Width="100"
x:Name="myComboBox" Margin="8"
ItemsSource="{Binding ListBoxListSource}"
SelectedIndex="{Binding ListBox}">
</ListBox>
In UserControl or Window Resources set up a few things....
ListBoxStyle - This styles the main container of the listbox, you can set the borders, margins, padding etc of the main box here. For my example I'm just getting rid of everything to de-style it.
<UserControl.Resources>
<Style x:Key="ListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
</Style>
</UserControl.Resources>
ItemContainerStyle - This is the bit that people say can't be re-styled - it contains the "windows-selector-blue" bar when an item is selected, but fear not this too can be re-styled (merge this UserControl.Resources section in combination with the above one).
This section is> changing the template of the ItemContainer from whatever it is to a Border, setting a top margin of 3 to pad things out and setting up a style. All we're doing with this style is adding 3px transparent border to the left and right of the item. Then in the Triggers>IsSelected (target of myBorder), changing the border Brush to Red.
<UserControl.Resources>
<Style x:Key="ItemContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="myBorder"
Padding="0" Margin="0 3 0 0"
SnapsToDevicePixels="true"
Style="{DynamicResource borderContent}">
<ContentPresenter />
</Border>
<ControlTemplate.Resources>
<Style x:Key="borderContent" TargetType="Border">
<Setter Property="BorderThickness" Value="3 0 3 0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Style>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="myBorder" Property="BorderBrush" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
ListBoxItemDataTemplate - The next step is to make the item container that displays your data. In my example the YourTextBlockStyler has a trigger on the Text>binding and changes the foreground and background colours of the text. Take note that the foreground and background of the Listbox style are set to transparent, so you have to over ride them in your TextBlock style if you want to see anything.
<UserControl.Resources>
<DataTemplate x:Key="ListBoxItemDataTemplate">
<TextBlock Text="{Binding}" Style="{StaticResource YourTextBlockStyler}"/>
</DataTemplate>
</UserControl.Resources>
Back to the listbox - Now we've set up all the styles and templates in the Resources section we can update the listbox with Style="" ItemContainerStyle="" and ItemTemplate=""
<ListBox Width="100"
x:Name="myComboBox" Margin="8"
ItemsSource="{Binding ListBoxListSource}"
SelectedIndex="{Binding ListBox}"
Style="{StaticResource ListBoxStyle}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
ItemTemplate="{StaticResource ListBoxItemDataTemplate}">
</ListBox>
Then your boring list box will transform magically in to a totally restyled list box with red border selector
From into
All without editing a single System.ResourceBrush =]

WPF Propagating GotFocus over the visualtree

I Have this Style template
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Focusable="True"
Panel.ZIndex="2">
</TextBox>
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And In a Custom Control have a fiel that uses this template:
<TextBox x:Name="DatoABuscar"
Height="Auto"
MinHeight="25"
Text="{Binding Filtro,UpdateSourceTrigger=PropertyChanged}"
Margin="1,1,1,0"
PreviewKeyDown="DatoABuscar_PreviewKeyDown"
VerticalAlignment="Center"
Style="{StaticResource placeHolder}"
Tag="{x:Static resources:Labels.CONTROLES_SearchPlaceHoderText}"
GotFocus="DatoABuscar_GotFocus"/>
As you cold see I have a GotFocus handler with this code:
private void DatoABuscar_GotFocus(object sender, RoutedEventArgs e)
{
((TextBox)sender).SelectAll();
}
This handle Works perfect and I pretend to select all the content of the textbox when GotFocus Happens, but If I understand the real textbox showed after GotFocus happen is textSource inner into the style template.
Now My Questions are?
How can I do to propagate the got focus received by DatoAbuscar to textSource?
or
How can i do to Access the visualtree under the DatoABuscar to get textSource?
or
How can i do to Select all text in textSource when DatoAbuscar recieves the GotFocus**?
Another aproach ?
EDIT: I'm totally wrong the problem isn't the TexBox where I'm selecting the text. My problema was the method to select the text. Finally I Implement This Post
Actually you only need to use FindName to find the "textSource".
private void DatoABuscar_GotFocus(object sender, RoutedEventArgs e)
{
var txt = sender as TextBox;
var innerTxt = txt.Template.FindName("textSource", txt) as TextBox;
Keyboard.Focus(innerTxt);
innerTxt.SelectAll();
}

Binding content of contentPresenter in UserControl?

I've got a UserControl which is a modified toggleButton.
I've added two String properties to it so I can change (or bind) them in blend, which I want to be the text displayed when the button is toggled. ie when checked, one string is displayed, when unchecked - the other.
Setting the text is fine, and toggling the UserControl is fine, but I don't know how to set the content of the contentpresenter from a property of the toggle by a trigger. Here's a rough look at the code:
<UserControl
x:Name="UserControl"
<UserControl.Resources>
<Style x:Key="BiTextToggleButtonWithBorder" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Path x:Name="path"
Data="M28,0.5 L28.071953,0.50129622 28.092436,0.5 115.90756,0.5 C117.89162,0.50000113 119.5,2.5147196 119.5,5.0000013 L119.61492,36.460156 119.61432,36.857203 C117.1338,37.367692 108.82679,39.239366 106.37993,47.492391 L44.667,47.5 28.092436,47.5 4.9999995,47.5 C2.5147185,47.5 0.5,45.485283 0.5,43 L0.5,21 0.51801485,20.64324 0.5,20.0835 C0.5,9.2678322 12.812169,0.50000072 28,0.5 z"
Stretch="Fill"
<ContentPresenter
x:Name="contentPresenter"
Content="{Binding}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" TargetName="contentPresenter" Value="{Binding whatgoeshere!?}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" TargetName="contentPresenter" Value="whatgoeshere!?"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<ToggleButton
x:Name="ToggleButton"
Style="{DynamicResource BiTextToggleButtonWithBorder}"
FontSize="18.667"
Foreground="{DynamicResource WhiteText}"/>
</Grid>
</UserControl>
I can't even find the property I want to change. I've done similar bindings to objects within a UserControl before, but nothing that is in a style and in a controlpresenter.
What am I missing?
have you tried changing the {Binding} to a {TemplateBinding} ? (MSDN documentation here)

Categories