I want to bind a ListBox SelectedItem to
This is my code for Listbox in my UserControl.xaml
Style x:Key="listbox" TargetType="ListBox">
<!-- Region Setter Properties -->
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type program:UserControl}}, Path=Source}" />
`<ListBox Name="ListBox"
Grid.Row="1"
SelectedIndex="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type program:UserControl}},
Path=SelectedIndex}"
SelectedItem="{Binding Path=(program:UserControl.SelectedItem),
RelativeSource={RelativeSource AncestorType={x:Type program:UserControl}}}"
Style="{DynamicResource listbox}" />`
In my UserControl.xaml.cs
public object SelectedItem
{
get { return (object) GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public int SelectedIndex
{
get { return (int) GetValue(SelectedIndexProperty); }
set { SetValue(SelectedIndexProperty, value); }
}
/// <summary>
/// Identifies the <see cref="Selected" /> dependency property.
/// </summary>
public static readonly DependencyProperty SelectedProperty = DependencyProperty.Register(
SelectedPropertyName,
typeof(object),
typeof(TileContainer),
new UIPropertyMetadata(default(object)));
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof (object), typeof (UserControl), new PropertyMetadata(default(object)));
public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register("SelectedIndex", typeof (int), typeof (UserControl), new PropertyMetadata(default(int)));
Normally it works, infact ItemsSource of my ListBox is correctly taken but SelectedIndex and SelectedItem don't work. I looked around the net but i didn't find any solution because maybe they don't have this issue.
I'm compiling with .NET 4.5 .
Thanx!
Update you DependencyProperty like so
public static readonly DependencyProperty SelectedProperty = DependencyProperty.Register(
SelectedPropertyName,
typeof(object),
typeof(TileContainer),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Related
I would like to have an standar tooltip for all the controls, setting the initial delay, the show delay and that it can be shown when is not enabled. In the control I only would need to set the text of the tooltip in each case.
I have this style:
<sys:Int32 x:Key="TooltipInitialShowDelay">2000</sys:Int32>
<sys:Int32 x:Key="TooltipInitialShowDelayLong">5000</sys:Int32>
<sys:Int32 x:Key="TooltipDisplayTime">60000</sys:Int32>
<Style TargetType="ToolTip" x:Key="ToolTipDefaultStyle">
<Setter Property="ToolTipService.ShowOnDisabled" Value="true"/>
<Setter Property="ToolTipService.InitialShowDelay" Value="{StaticResource TooltipInitialShowDelay}"/>
<Setter Property="ToolTipService.ShowDuration" Value="{StaticResource TooltipDisplayTime}"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PlacementTarget.(dp:ToolTipDependencyProperty.Texto), RelativeSource={RelativeSource AncestorType=ToolTip}}" MaxWidth="400" TextWrapping='Wrap' />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I have this dependency properties:
public static class ToolTipDependencyProperty
{
#region Texto
public static readonly DependencyProperty TextoProperty =
DependencyProperty.RegisterAttached(
"Texto",
typeof(string),
typeof(ToolTipDependencyProperty));
public static string GetTexto(DependencyObject obj)
{
return (string)obj.GetValue(TextoProperty);
}
public static void SetTexto(DependencyObject obj, string value)
{
obj.SetValue(TextoProperty, value);
}
#endregion Texto
#region InitialShowDelay
public static readonly DependencyProperty InitialShowDelayProperty =
DependencyProperty.RegisterAttached(
"InitialShowDelay",
typeof(int),
typeof(ToolTipDependencyProperty));
public static int GetInitialShowDelay(DependencyObject obj)
{
return (int)obj.GetValue(InitialShowDelayProperty);
}
public static void SetInitialShowDelay(DependencyObject obj, int value)
{
obj.SetValue(InitialShowDelayProperty, value);
}
#endregion InitialShowDelay
#region ShowDuration
public static readonly DependencyProperty ShowDurationProperty =
DependencyProperty.RegisterAttached(
"ShowDuration",
typeof(int),
typeof(ToolTipDependencyProperty));
public static int GetShowDuration(DependencyObject obj)
{
return (int)obj.GetValue(ShowDurationProperty);
}
public static void SetShowDuration(DependencyObject obj, int value)
{
obj.SetValue(ShowDurationProperty, value);
}
#endregion ShowDuration
}
And this is my button:
<Button Name="btnBuscar" Content="Buscar" Command="{Binding BuscarCommand}"
IsEnabled="{Binding BuscarIsEnabled}"
dp:ToolTipDependencyProperty.Texto="{Binding BuscarToolTip}">
<Button.ToolTip>
<ToolTip Style="{StaticResource ToolTipDefaultStyle}"/>
</Button.ToolTip>
</Button>
The problem is that the text is ahown, but only when the button is enabled. And also the initial show delay and show duration is the standard duration, not the values that I want to use.
However, if in the control I set the ToolTip.Service variables, it works.
How could I set the duration in the style?
Thanks.
The ToolTipService attached properties need to be set on the element that owns the tooltip, not the tooltip itself.
You'll need to create a style for Button, or FrameworkElement.
I'm trying to change my UserControl's Border.BorderBrush property depending on if the Mouse enters, leaves, or is down on my UserControl. I've tried doing it explicitly in the code behind, but anytime the Border.BorderBrush property is changed, the border disappears.
I went down a string of possible solutions with no avail. As of my current codebase I'm attempting to use a Style and Triggers to manage it for me. My issue there is that there is no property for IsMouseDown unless you're dealing with a Button (at least that's what I've gathered from reading), so I defined a property for that.
Just when I think it's going to work, the border can't find my Style defined in UserControl.Resources.
I've exhausted everything I know to do, any help would be extremely appreciated.
XAML:
<UserControl x:Class="OSK.Resources.Themes.Default.Key"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OSK.Resources.Themes.Default"
mc:Ignorable="d"
x:Name="OSKuwuDefaultKey"
d:DesignHeight="48" d:DesignWidth="48">
<UserControl.Style>
<Style x:Name="KeyStyle">
<Style.Triggers>
<Trigger Property="Border.IsMouseOver" Value="true">
<Setter Property="Border.BorderBrush" Value="{Binding Path=BrushHover, RelativeSource={RelativeSource Self}}" />
</Trigger>
<Trigger Property="Border.IsMouseOver" Value="false">
<Setter Property="Border.BorderBrush" Value="{Binding Path=BrushNormal, RelativeSource={RelativeSource Self}}" />
</Trigger>
<Trigger Property="local:Key.IsMouseDown" Value="true">
<Setter Property="Border.BorderBrush" Value="{Binding Path=BrushDown, RelativeSource={RelativeSource Self}}" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<Border x:Name="key" Background="Transparent" Width="{Binding Path=Width, ElementName=OSKuwuDefaultKey}" Height="{Binding Path=Height, ElementName=OSKuwuDefaultKey}" BorderBrush="{Binding BorderBrush, ElementName=OSKuwuDefaultKey}" CornerRadius="{Binding Path=CornerRadius, ElementName=OSKuwuDefaultKey}" BorderThickness="{Binding Path=OutlineThickness, ElementName=OSKuwuDefaultKey}" MouseEnter="Key_MouseEnter" MouseLeave="Key_MouseLeave" MouseDown="Key_MouseDown" MouseUp="Key_MouseUp">
<Canvas>
<Label Content="{Binding SuperText, ElementName=OSKuwuDefaultKey}" Canvas.Top="6" Canvas.Left="8" />
<Label Content="{Binding SubText, ElementName=OSKuwuDefaultKey}" Canvas.Top="20" Canvas.Right="4" />
</Canvas>
</Border>
Code-Behind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace OSK.Resources.Themes.Default
{
/// <summary>
/// Interaction logic for Key.xaml
/// </summary>
public partial class Key : UserControl
{
public static readonly DependencyProperty SuperTextProperty = DependencyProperty.Register("SuperText", typeof(string), typeof(Key), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
public string SuperText
{
get
{
return (string)GetValue(SuperTextProperty);
}
set
{
SetValue(SuperTextProperty, value);
}
}
public static readonly DependencyProperty SubTextProperty = DependencyProperty.Register("SubText", typeof(string), typeof(Key), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
public string SubText
{
get
{
return (string)GetValue(SubTextProperty);
}
set
{
SetValue(SubTextProperty, value);
}
}
public static readonly DependencyProperty BrushNormalProperty = DependencyProperty.Register("BrushNormal", typeof(Brush), typeof(Key), new FrameworkPropertyMetadata(Brushes.LightSlateGray));
public Brush BrushNormal
{
get
{
return (Brush)GetValue(BrushNormalProperty);
}
set
{
SetValue(BrushNormalProperty, value);
}
}
public static readonly DependencyProperty BrushHoverProperty = DependencyProperty.Register("BrushHover", typeof(Brush), typeof(Key), new FrameworkPropertyMetadata(Brushes.LightSteelBlue));
public Brush BrushHover
{
get
{
return (Brush)GetValue(BrushHoverProperty);
}
set
{
SetValue(BrushHoverProperty, value);
}
}
public static readonly DependencyProperty BrushDownProperty = DependencyProperty.Register("BrushDown", typeof(Brush), typeof(Key), new FrameworkPropertyMetadata(Brushes.SlateGray));
public Brush BrushDown
{
get
{
return (Brush)GetValue(BrushDownProperty);
}
set
{
SetValue(BrushDownProperty, value);
}
}
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(int), typeof(Key), new FrameworkPropertyMetadata(4, FrameworkPropertyMetadataOptions.AffectsRender));
public int CornerRadius
{
get
{
return (int)GetValue(CornerRadiusProperty);
}
set
{
SetValue(CornerRadiusProperty, value);
}
}
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register("OutlineThickness", typeof(Thickness), typeof(Key), new FrameworkPropertyMetadata(new Thickness(1), FrameworkPropertyMetadataOptions.AffectsRender));
public Thickness OutlineThickness
{
get
{
return (Thickness)GetValue(OutlineThicknessProperty);
}
set
{
SetValue(OutlineThicknessProperty, value);
}
}
public static DependencyProperty IsMouseDownProperty = DependencyProperty.RegisterAttached("IsMouseDown", typeof(bool), typeof(Key), new FrameworkPropertyMetadata(default(bool)));
public bool IsMouseDown
{
get
{
return (bool)GetValue(IsMouseDownProperty);
}
set
{
SetValue(IsMouseDownProperty, value);
}
}
public Key()
{
InitializeComponent();
}
private void Key_MouseEnter(object sender, MouseEventArgs e)
{
//this.SetValue(Key.BorderBrushProperty, BrushNormal);
//Console.WriteLine(GetValue(Key.BorderBrushProperty));
}
private void Key_MouseLeave(object sender, MouseEventArgs e)
{
//this.SetValue(Key.BorderBrushProperty, BrushHover);
}
private void Key_MouseDown(object sender, MouseButtonEventArgs e)
{
//this.SetValue(Key.BorderBrushProperty, BrushDown);
this.SetValue(Key.IsMouseDownProperty, true);
}
private void Key_MouseUp(object sender, MouseButtonEventArgs e)
{
this.SetValue(Key.IsMouseDownProperty, false);
}
}
}
I got it working. The original post has the final working code.
And the layout should look like this, without explicitly setting the size of the Border:
<Border x:Name="key" Background="Transparent"
BorderBrush="{Binding BorderBrush, ElementName=OSKuwuDefaultKey}"
CornerRadius="{Binding CornerRadius, ElementName=OSKuwuDefaultKey}"
BorderThickness="{Binding OutlineThickness, ElementName=OSKuwuDefaultKey}"
MouseEnter="Key_MouseEnter"
MouseLeave="Key_MouseLeave"
MouseDown="Key_MouseDown"
MouseUp="Key_MouseUp">
<Canvas>
...
</Canvas>
</Border>
I am creating a user control which is a toggle button with image. I have separate dependency properties for image when the toggle button is checked and when the toggle button is not checked.
Xaml:
<ToggleButton IsChecked="{Binding Checked, Mode=TwoWay}">
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="{Binding CheckedImage}"></Setter>
<DataTrigger Binding="{Binding IsChecked}" Value="False">
<Setter Property="Source" Value="{Binding UncheckedImage}"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ToggleButton>
Code behind:
public partial class ImageToggleButton : UserControl
{
public ImageToggleButton()
{
InitializeComponent();
this.DataContext = this;
}
public bool Checked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
// Using a DependencyProperty as the backing store for IsChecked. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register("Checked", typeof(bool), typeof(ImageToggleButton), null);
public ImageSource CheckedImage
{
get { return (ImageSource)base.GetValue(TrueStateImageProperty); }
set { base.SetValue(TrueStateImageProperty, value); }
}
// Using a DependencyProperty as the backing store for TrueStateImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TrueStateImageProperty =
DependencyProperty.Register("CheckedImage", typeof(ImageSource), typeof(ImageToggleButton), null);
public ImageSource UncheckedImage
{
get { return (ImageSource)base.GetValue(FalseStateImageProperty); }
set { base.SetValue(FalseStateImageProperty, value); }
}
// Using a DependencyProperty as the backing store for FalseStateImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FalseStateImageProperty =
DependencyProperty.Register("UncheckedImage", typeof(ImageSource), typeof(ImageToggleButton), null);
}
MainWindow:
<ImageToggleButton Checked="{Binding IsPlaying}" CheckedImage="{DynamicResource PauseIcon}" UncheckedImage="{DynamicResource PlayIcon}">
</ImageToggleButton>
Is it possible to use CheckedImage as a default image so that if I am not providing UncheckedImage, then in both checked and unchecked state will show CheckedImage?
You could register a PropertyChangedCallback for the CheckedImage property that sets the value of the other one:
public static readonly DependencyProperty TrueStateImageProperty =
DependencyProperty.Register("CheckedImage", typeof(ImageSource), typeof(ImageToggleButton),
new PropertyMetadata(new PropertyChangedCallback(OnPropChanged)));
private static void OnPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ImageToggleButton tb = (ImageToggleButton)d;
if (tb.UncheckedImage == null)
tb.UncheckedImage = (ImageSource)e.NewValue;
}
By the way, you should following the dependency property naming conventions: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/custom-dependency-properties
In a WPF window, I'm trying to put the cursor by default on one of the textboxes.
After reading some questions and answers, I tried the following:
xaml:
<StackPanel Grid.Row="1"
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding UserShouldEditValueNow}" Value="true">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=FID}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<TextBox Name ="FID" Text="{Binding FixID, UpdateSourceTrigger=PropertyChanged}"
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
</StackPanel>
cs: (Viewmodel)
this.UserShouldEditValueNow = true;
I expected to see a blinking cursor on the textbox FID when opening the window.
However, there's no cursor at all on this textbox.
Debugging showed me that I'm going through the cs code, setting the value to true.
any ideas why?
Solution involves:
1. Adding a FocusExtension class.
2. Focus and Keyboard.Focus are inside Dispatcher.BeginInvoke
cs.
public static class FocusExtension
{
public static bool GetIsFocused(DependencyObject obj)
{
return (bool)obj.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject obj, bool value)
{
obj.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached(
"IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Dispatcher.BeginInvoke(
new Action(
delegate{
uie.Focus();
Keyboard.Focus(uie);
}
)
);
}
}
}
.xaml
<TextBox Text="{Binding FixID, UpdateSourceTrigger=PropertyChanged}" viewModels:FocusExtension.IsFocused="{Binding UserShouldEditValueNow}" />
I want to bind a DependencyProperty and DataContext to my UserControl. DataContext is working, but Setting the DependencyProperty has no effect. This is my UserControl:
<MyProperty:MyPropertyControl DataContext="{Binding SelectedPerson}" IsEnabled="True"/>
And this is the CodeBehind of my UserControl:
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.Register(
"IsEnabled",
typeof(Boolean),
typeof(MyProperty:MyPropertyControl),
new FrameworkPropertyMetadata()
{
DefaultValue = false,
BindsTwoWayByDefault = false,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
});
public MyPropertyControl()
{
InitializeComponent();
}
public Boolean IsEnabled
{
get { return (Boolean)GetValue(IsEnabledProperty); }
set
{
SetValue(IsEnabledProperty, value);
NotifyPropertyChanged("IsEnabled");
}
}
I can set the property IsEnabled to true or false, but it has no effect.
User Control Code:
<Button Content="Test" Width="100" Height="30" IsEnabled="{Binding IsEnabled}" />
You'll have to set the source object of the Binding to the UserControl, e.g. like this:
<Button ... IsEnabled="{Binding IsEnabled,
RelativeSource={RelativeSource AncestorType=UserControl}}" />