Binded Grid´s Width - but didn't refresh - wpf

I binded a Grid´s Width in WPF:
<Grid Width="{Binding MDIWidth, RelativeSource={RelativeSource AncestorType=dx:DXWindow}}" Name="GridControl">
...
</Grid>
The property is changed, but the Grid didn't refresh it´s size, if the property is changed. How to achieve this?

I can only suggest that your Binding is not working because you can set the Grid.Width property using a Binding. If you are using the RelativeSource Binding to access the code behind of the UserControl where this Grid is, then try this as a test... in the constructor:
public DXWindow()
{
InitializeComponent();
DataContext = this;
MDIWidth = 100.0;
}
Then in the view:
<Grid Width="{Binding MDIWidth}" Name="GridControl" />
If this works, then your original Binding has an error.
UPDATE >>>
If you are using the code behind of a UserControl to declare your property, then you will need to declare a DependencyProperty:
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
"Width", typeof(double), typeof(MainWindow), new UIPropertyMetadata(250.0));
public double Width
{
get { return (double)GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); }
}
Apart from you possibly not using a DependencyProperty, I don't know why else your code doesn't work... you certainly can update the Width of a Grid at any time using a Binding.

Related

Binding a Color to a DependencyProperty in UserControl

I have a UserControl that has a Grid with a Background property that is bound. All of my other bindings work as expected, but for some reason, the only color I get in my UserControl is the default value I set for the DependencyProperty.
Referencing the UserControl in MainWindow.xaml:
<controls:MyUserControl Title="{Binding Path=MyObjects[0].Title" MyControlColor="{Binding Path=MyObjects[0].Color}" />
Title shows up as expected but the color is unchanged.
MyUserControl code (I use MyControlColorBrush for the color source, which just converts MyControlColor to a SolidColorBrush. Code on down.):
<Grid Background="{Binding Path=MyControlColorBrush, RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Grid>
MyUserControl.xaml.cs code:
public Color MyControlColor
{
get { return (Color)GetValue(MyControlColorProperty); }
set { SetValue(MyControlColorProperty, value); }
}
public static readonly DependencyProperty MyControlColorProperty = DependencyProperty.Register("MyControlColor", typeof(Color), typeof(MyUserControl), new PropertyMetadata(Colors.Black));
And then a property that just converts the color to a SolidColorBrush:
public SolidColorBrush MyControlColorBrush
{
get { return new SolidColorBrush(MyControlColor); }
}
Any ideas on what I could be missing? If I check the value of MyControlColor, it's showing the right color, but the background of the Grid just isn't changing from Black.
The binding to MyControlColorBrush only happens once when your page is first loaded. Your binding to MyObjects[0].Color is causing your dependency property to update but there's nothing indicating to the rest of your app that MyControlColorBrush needs to be updated as well.
There are a few ways to achieve this, the easiest is probably to just create a read-only dependency property for your brush that you update whenever you detect a change in your color property (this is similar to how the Width/ActualWidth properties work). Your control will need a DP for the color:
public Color MyControlColor
{
get { return (Color)GetValue(MyControlColorProperty); }
set { SetValue(MyControlColorProperty, value); }
}
public static readonly DependencyProperty MyControlColorProperty =
DependencyProperty.Register("MyControlColor", typeof(Color), typeof(MyUserControl),
new PropertyMetadata(Colors.Black, OnColorChanged));
And then a read-only DP for the brush:
public Brush MyControlColorBrush
{
get { return (Brush)GetValue(MyControlColorBrushProperty); }
protected set { SetValue(MyControlColorBrushPropertyKey, value); }
}
private static readonly DependencyPropertyKey MyControlColorBrushPropertyKey
= DependencyProperty.RegisterReadOnly("MyControlColorBrush", typeof(Brush), typeof(MyUserControl),
new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.None));
public static readonly DependencyProperty MyControlColorBrushProperty = MyControlColorBrushPropertyKey.DependencyProperty;
And you'll update the brush whenever your color DP changes:
private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MyUserControl).MyControlColorBrush = new SolidColorBrush((Color)e.NewValue);
}
GUI elements in your custom control then bind to the read-only DP, e.g.:
<Grid Background="{Binding Path=MyControlColorBrush, RelativeSource={RelativeSource AncestorType=local:MyUserControl}}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

WPF : binding in UserControl and Page

I cannot properly bind to a UserControl property placed in a Page.
I have this UserControl :
<UserControl x:Class="xxxx.NumericBox" (...)>
<TextBox Name="TextBoxValue" Text="{Binding RelativeSource {RelativeSource AncestorType=UserControl}, Path=Value, Mode=TwoWay}" (...)
With this behind code :
public partial class NumericBox : UserControl
{
public NumericBox()
{
InitializeComponent();
}
public uint? Value
{
get => (uint?)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(uint?), typeof(NumericBox), new PropertyMetadata(null));
The UserControl contains others controls witch interract with Value property (+/-) and it works fine.
But I create the DependencyProperty to also bind the value in parent page.
A exemple of code in a page where I inject the UserControl :
var binding = new Binding("Line.Quantity");
binding.Mode = BindingMode.TwoWay;
var numeric = new NumericBox();
numeric.SetBinding(ValueProperty, binding);
The binding works on startup but not update Line.Quantity when I modify the Textbox...
The Line class implements INotifyPropertyChanged and notify change on Quantity.
What is the correct way to do that ?
I have seen this question but but I have not been able to correct my code :
Binding on DependencyProperty of custom User Control not updating on change

How to define a dependency property in a user control that just bubbles up a value from one of its children?

I am creating a ToggleSwitchItem user control, which contains a ToggleSwitch and a TextBlock. I have defined a dependency property called IsChecked which I just want to use to expose the IsChecked property of the private ToggleSwitch child.
But the data binding doesn't work... It just stays at the default value when loaded.
What am I missing?
Code:
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register(
"IsChecked",
typeof(bool),
typeof(ToggleSwitchItem),
new PropertyMetadata(new PropertyChangedCallback
(OnIsCheckedChanged)));
public bool IsChecked
{
get
{
return (bool)GetValue(IsCheckedProperty);
}
set
{
SetValue(IsCheckedProperty, value);
}
}
private static void OnIsCheckedChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ToggleSwitchItem item = (ToggleSwitchItem)d;
bool newValue = (bool)e.NewValue;
item.m_switch.IsChecked = newValue;
}
for the data binding, I'm using to following:
<phone:PhoneApplicationPage.Resources>
<myApp:SharedPreferences x:Key="appSettings"/>
</phone:PhoneApplicationPage.Resources>
IsChecked="{Binding Source={StaticResource appSettings},
Path=SomeProperty, Mode=TwoWay}"
The SharedPreferences class is working fine, as it works without issue when bound to a plain vanilla ToggleSwitch's IsChecked property exactly as per above.
Thanks!
SOLUTION (with help from Anthony):
I bind my child toggle switch to my user control in the user control's constructor like so:
Binding binding = new Binding();
binding.Source = this;
binding.Path = new PropertyPath("IsChecked");
binding.Mode = BindingMode.TwoWay;
m_switch.SetBinding(ToggleSwitch.IsCheckedProperty, binding);
And I remove the callback as I no longer need it:
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register(
"IsChecked",
typeof(bool),
typeof(ToggleSwitchItem),
null);
public bool IsChecked
{
get
{
return (bool)GetValue(IsCheckedProperty);
}
set
{
SetValue(IsCheckedProperty, value);
}
}
I can't quite see what is actually wrong with the code you've show so far, except that you haven't show how the user toggling the switch would actually cause the IsChecked property to change.
Have you try using binding inside the UserControl:
<ToggleButton IsChecked="{Binding Parent.IsChecked, ElementName=LayoutRoot, Mode=TwoWay}" />
You do not need the OnPropertyChanged callback with this approach.
Check the DataContext of your control.Which means 2 things : All instances of your control must have right DataContext to work -ok-, and also you should not 'break' this DataContext when you define the control (at the Class level). If, when you define your control, you set the DataContext to 'this' / Me in code or to 'Self' in xaml, it nows refer only to itself and forget about the DataContext in which it is when you instanciate it in your application -- Binding fails.
If you have to refer to your control's properties within your control Xaml, use a binding with findAncestor / AncestorType = ToggleSwitchItem Or name your control in Xaml and bind with its ElementName.
Maybe this could help
public bool IsChecked
{
get { return GetValue(IsCheckedProperty) is bool ? (bool) GetValue(IsCheckedProperty) : false; }
set
{
SetValue(IsCheckedProperty, value);
}
}

WPF: DependencyProperty refusing to work

I'm trying to register 3 dependency properties on a Window to control it's formatting. I've looked over and over the code but I must be missing something.
public static readonly DependencyProperty TextColorProperty = DependencyProperty.Register("TextColor", typeof(Color), typeof(WinStickyFingers), new PropertyMetadata(Colors.White));
public Color TextColor {
get { return (Color)base.GetValue(TextColorProperty); }
set { base.SetValue(TextColorProperty, value); }
}
public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register("BackgroundColor", typeof(Color), typeof(WinStickyFingers), new PropertyMetadata(Colors.Black));
public Color BackgroundColor {
get { return (Color)base.GetValue(BackgroundColorProperty); }
set {
base.SetValue(BackgroundColorProperty, value);
}
}
<TextBlock DockPanel.Dock="Top" Text="{Binding Name}" Foreground="{Binding TextColor,Converter={StaticResource DebugConverter}}" Background="{Binding Path=BackgroundColor}" />
I'm using Bea Stollnitz's debugging method but my breakpoint isn't even triggered.
What is the DataContext of the TextBlock? How does it know that it is supposed to bind to the properties on your Window?
You need to either set DataContext to the Window instance, or set the Source (or RelativeSource, or ElementName) properties on your bindings. All of these properties exist as a means of resolving the bound object for your Binding. DataContext is a fallback if none of the others is set, but I'm guessing that you haven't set that either.

How to bind to a WPF dependency property when the datacontext of the page is used for other bindings?

How to bind to a WPF dependency property when the datacontext of the page is used for other bindings? (Simple question)
The datacontext of the element needed to be set.
XAML:
<Window x:Class="WpfDependencyPropertyTest.Window1" x:Name="mywindow">
<StackPanel>
<Label Content="{Binding Path=Test, ElementName=mywindow}" />
</StackPanel>
</Window>
C#:
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test",
typeof(string),
typeof(Window1),
new FrameworkPropertyMetadata("Test"));
public string Test
{
get { return (string)this.GetValue(Window1.TestProperty); }
set { this.SetValue(Window1.TestProperty, value); }
}
Also see this related question:
WPF DependencyProperties
In XAML:
Something="{Binding SomethingElse, ElementName=SomeElement}"
In code:
BindingOperations.SetBinding(obj, SomeClass.SomethingProperty, new Binding {
Path = new PropertyPath(SomeElementType.SomethingElseProperty), /* the UI property */
Source = SomeElement /* the UI object */
});
Though usually you will do this the other way round and bind the UI property to the custom dependency property.

Resources