I am trying to implement dragdrop functionality in Listbox(with in the listbox). For dragging i am using Thumb control (Mythumb is the class inherited from thumb)
so i have set the items panel to Canves and set the style for list box item to following
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="150" />
<Setter Property="Margin" Value="5,2" />
<Setter Property="Padding" Value="3" />
<Setter Property="dcc:OutputConfigurationPanel.Left" Value="{Binding Left}"></Setter>
<Setter Property="dcc:OutputConfigurationPanel.Top" Value="{Binding Top}"></Setter>
<Setter Property="IsSelected" Value="{Binding IsSelected}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid DockPanel.Dock="Bottom" >
<Grid>
<Border BorderBrush="Black" Background="Black">
<ContentPresenter x:Name="ContentHost" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<MythumbTemplate="{StaticResource MoveThumbTemplate}" Cursor="Hand" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter Property="Background" Value="#FF233B00" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The drag drop is working fine but the thumb doesn’t allow the item to be selected. After checking i found that the mousedown event is not firing.
Is there a way to enable the select the items in usual ways?
A Thumb will always eat mouse clicks, same as button.
As I see it, you have two options:
From the code of the thumb, search up until you find the list box item and then set it's IsSelected property to true.
Scrap the thumb and create a Behavior that deals with dragging but doesn't handle mouse events (i.e. doesn't set e.Handled=true;) - this will preserve list box functionality.
Option 1 is probably faster, but I'd strongly consider to go with option 2 - less meddling with core controls functionality = better.
Related
I would like to make a game like Shakes & Fidgets. I got stuck at the Main menu, where I already overcomplicated stuff as I always do. I made a grid layout, where I will put the buttons, but every button is a picture. I use ImageBrush for every button's picture I want to create.
I would like to create ONE style for every button so they change their backgrounds based on the x:Name or x:Key they have. So a Button with x:Name or x:Key "PlayGame" would find it's as the PlayGame.png, PlayGame_Hover, PlayGame_OnClick where "PlayGame" is a variable.
In other words I would like to have a style that can filter the x:name, or x:key of a button, and uses it as a variable later on so I can do this: {StaticResource VARIABLENAME}
The Code I have now is:
<ImageBrush x:Key="PlayGame">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<ImageBrush x:Key="PlayGame_Hover">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton_Hover.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<ImageBrush x:Key="PlayGame_OnClick">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton_OnClick.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource PlayGame}" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource PlayGame_Hover}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource PlayGame_OnClick}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I found a not very effective solution, but not the one I actually want
You can give the Style an
x:Key="styleKey"
and you have to give the button this part:
Style="{StaticResource styleKey}"
This way you will have to make a style for every different button you want to have, but it will work, and you will be happy about it if efficency is not key.:D
I'd like to have a Radio Button whose IsEnable property doesn't make any change in its visual appearance. However, the Radio Button shouldn't allow user to do anything when its IsEnable property is False.
I just want want to have a Radio Button which looks same irrespective of its IsEnable property. Apart from Visual appearance everything else should work as it is.
You may find it as a strangest requirement. But I want to achieve this. I'm using Radio Buttons as List Box items in List Box. Everything works good, but the problem occurs when user do Ctrl Mouse Left Click on checked Radio button. That's where everything fails.
Please help me.
You will have to extract the ControlTemplate of a RadioButton and then remove the style for Disable trigger. Below is an example of a standard template for a RadioButton. Just comment out the trigger IsEnable = False
<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="#F4F4F4"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Themes:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" IsRound="true" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ashwin,
Its Very simple
Just follow the steps.
Right Click on the RadioButton, Edit Template and Edit a Copy
Then go to the Style created and comment out the code in storyboard of Disabled Visual state as shown in this image "http://i.stack.imgur.com/3TNoR.png"
Then it must look same for both states.
Take a look at the result "http://i.stack.imgur.com/fCL47.png"
Hope it solved your purpose.
Thanks,
I'm attempting to style the ListBoxItems within my listbox but the content of the ListBoxItem does not display and any change in colours are not apparent. The only thing working is the "border bottom" that I've applied to the bottom of each list item.
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" />
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use a panel/container/decorator in the ListBoxItem control template to set the background color. (It seems that the logic for setting the selection background color will interfere with attempts to control its background color.)
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
Name="PART_Border"
Focusable="true"
Background="{TemplateBinding Background}"
BorderBrush="#FF66AFDE"
BorderThickness="0 0 0 1"
>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter
Property="Background"
Value="Red"
TargetName="PART_Border"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Also note, that Border.Focusable is by default false. If setting it to true doesn't work (i admit, i haven't tested), use a different container control instead of Border.
Also, if the content you will show has any controls receiving focus (such as buttons or text fields), the trigger might not work as expected, because the Border might not have the focus when a control of the content has the focus. Also, tabbing from control to control might exhibit unexpected behaviour. If you have to deal with such a situation, try to handle the trigger in an ItemTemplate instead.
Regarding the ContentPresenter not showing anything: Depending on the type of the elements in the ItemsSource, you might need to define a ListBox.ItemTemplate (or ListBox.ItemTemplateSelector), otherwise ContentPresenter might not know what to display.
Try this
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" x:Name="border">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="border" Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I hope this will help
First of all, I would like to add customized text blocks to my GUI with the least possible overhead. For instance: <TextBlock style={StaticRessources myTextBlock}>Text</TextBlock>
For now I have the following border style:
<Style x:Key="greenBox" TargetType="Border">
<Setter Property="Background" Value="#00FF00"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="100"/>
</Style>
And I apply it in the following way:
<Border Style="{StaticResource greenBox}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Custom Text</TextBlock>
</Border>
My problem is, it needs 2 Tags and the properties set in the TextBlock will be redunant. I cannot figure out how to abstract both definitions into a single element.
that's where Label comes into play:
<Style TargetType="Label" x:Key="greenLabel">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Border Style="{StaticResource greenBox}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Label Style="{StaticResource greenLabel}">Custom Text</Label>
(in accordance with your other question: if this is the only place you use that borderstyle you can of course include these directly in that border not using an extra style)
You would need to create a custom control as described here. Or you could create a UserControl as well.
I have been using a custom RadioButton control with a ToggleButton as the control template. Here's what the xaml looks like:
<RadioButton.Template>
<ControlTemplate>
<ToggleButton x:Name="tb" IsChecked="{Binding IsChecked, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
Content="{TemplateBinding RadioButton.Content}"
PreviewMouseDown="tb_PreviewMouseDown">
</ToggleButton>
</ControlTemplate>
</RadioButton.Template>
It's been working well, except when I try to either programatically set a button's IsChecked property, or make a binding with it. Then the button that should be checked is visually unresponsive - it doesn't appear to be pressed, and the Aero mouse over effect does not appear. The Clicked event handler still works, and the IsChecked property of both the RadioButton and the ControlTemplate's toggle button are true when I examine their values. Amy I doing something wrong with the binding? Any ideas?
Here's an example of how I use it in the application:
<local:RadioToggleButton Content="1Hr" GroupName="Interval" x:Name="oneHrBtn"
IsChecked="{BindingPath=oneHrBtnIsChecked, Mode=TwoWay}" Margin="2 5 3 5"
IsEnabled="{Binding Path=oneHrBtnIsEnabled, Mode=TwoWay}"/>
What you have is very strange. The RadioButton class derives from ToggleButton. So effectively you put a button in a button. Are you simply trying to make the RadioButton look like a ToggleButton? If so, why don't you use ToggleButton directly?
If you want to make the RadioButton look like a ToggleButton so you can use the GroupName feature, then you'd have to copy the ToggleButton control template and use that (not embed a ToggleButton in the control template).
You can get the default templates from here. Then search for the ToggleButton style and copy it's ControlTemplate.
EDIT:
The following example shows how this can be done. You just need to add a reference to PresentationFramework.Aero.
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackground" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#F3F3F3" Offset="0" />
<GradientStop Color="#EBEBEB" Offset="0.5" />
<GradientStop Color="#DDDDDD" Offset="0.5" />
<GradientStop Color="#CDCDCD" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070" />
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeThickness="1" Stroke="Black" StrokeDashArray="1 2" SnapsToDevicePixels="true" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<theme:ButtonChrome Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
SnapsToDevicePixels="true">
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</theme:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Chrome" Property="RenderDefaulted" Value="true" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Chrome" Property="RenderPressed" Value="true" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<RadioButton GroupName="TestGroup">Option 1</RadioButton>
<RadioButton GroupName="TestGroup">Option 2</RadioButton>
</StackPanel>
</Window>
If all you want is a RadioButton which looks like a ToggleButton, you can actually implicitly refer to ToggleButton's style as a static resource by its type:
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" />
This seems to work because RadioButton is descended from ToggleButton. So you can't, for example, use {StaticResource {x:Type ComboBox}}.
I'm not able to track down any documentation for using an x:Type as a resource for Style; I'd be interested to see it, if anyone out there knows where to look.
So the issue with my custom RadioToggleButton control was being caused by something very weird indeed. I will describe my solution below, not because I expect anyone else to run into this particular problem, but just as an example of a solution that seems unconnected to the problem.
There was a binding on IsEnabled property of the GroupBox containing the button group. This binding seemed to work fine, enabling and disabling all the internal controls when appropriate. But as soon as I removed this binding, the problem I described above disappeared. This is not ideal, but I decided that I had spent too much time on this issue, so I bound the IsEnabled properties of the individual controls to the same property that the GroupBox had been bound to, and now at least I have the behavior I wanted.