I wrote a custom control for DateTimePicker, but the binding value is not passed to the property correctly.
<cc:DateTimePicker SelDate="{Binding RA_EFFECTIVE_DATE}"/> <!-- Doesn't work -->
<cc:DateTimePicker SelDate="1.1.2014"/> <!-- Works? Which means I can see the value inside setter SelDate correctly -->
Here is my DateTimePicker class:
public static readonly DependencyProperty SelDateProperty =
DependencyProperty.Register(
"SelDate",
typeof(DateTime?),
typeof(DateTimePicker),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedDateChanged, CoerceSelectedDate));
public DateTime? SelDate
{
get { return (DateTime?)GetValue(SelDateProperty); }
set { SetValue(SelDateProperty, value); }
}
Thanks in advance...
Related
I wrote a customcontrol inhert Control and add a DependencyProperty content which I want it to be the same as the content of the button control.
Here is the code:
[System.ComponentModel.Bindable(true)]
public object Content
{
get { return (object)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
// Using a DependencyProperty as the backing store for Content. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(object), typeof(SContent), null);
But after I reference the dll and run the program, WPF threw this error:
What's wrong with this? Would you please help me? Thank you.
If you want your custom control to support direct content in XAML, you should decorate it with the ContentPropertyAttribute :
[ContentProperty("Content")]
public class SContent : Control
{
[System.ComponentModel.Bindable(true)]
public object Content
{
get { return GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content), typeof(object), typeof(SContent), null);
}
But if you just want a Content property you might as well inherit from ContentControl instead of Control. Then you also get a ContentTemplate property and some other stuff "for free".
I've created a custom control, means a class deriving from control associating a default lookless theme defined via Themes/Generic.xaml. So far so good.
Now, I want to use the control like any other of the main WPF-controls (textbox, listbox, label, textblock, ...) and bind to the defined properties.
The custom control defines a property called Value, that I like to set a Binding to. But nothing ever is written to the bound property in the DataContext.
Well, here's what I've got so far:
In Custom Control class, there is as follows:
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(string), typeof(MyClass),
new FrameworkPropertyMetadata("", new PropertyChangedCallback(onValuePropertyChangedCallback)));
private static void onValuePropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
MyClass myClass = (MyClass)sender;
myClass.Value = (string)args.NewValue;
}
public string Value
{
get { return (string) GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
When I use the control, it's like that
<local:MyClass MyValue="{Binding CurrentValue}" ... />
The CurrentValue-property of the DataContext is never affected, never changes it's value.
What am I doing wrong?
The Binding to should be two-way in order to update the source property:
<local:MyClass Value="{Binding CurrentValue, Mode=TwoWay}" ... />
If you want this to be the default binding mode, you could set an appropriate flag when you register your property:
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
nameof(Value), typeof(string), typeof(MyClass),
new FrameworkPropertyMetadata(
"", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
Note that your onValuePropertyChangedCallback was entirely redundant. You don't need to set the property again, when its value has just changed.
I have a simple User Control:
public partial class FreqSpreadUC : UserControl
{
public FreqSpreadUC()
{
InitializeComponent();
FreqOne = "trying to pass this on to the parent";
}
public String FreqOne
{
get { return (String)GetValue(FreqOneProperty); }
set { SetValue(FreqOneProperty, value); }
}
// Using a DependencyProperty as the backing store for FreqOne. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FreqOneProperty =
DependencyProperty.Register("FreqOne", typeof(String), typeof(FreqSpreadUC));
}
Then I am consuming it as follows:
<spread:FreqSpreadUC FreqOne="{Binding TestFreqOne}" />
When the underlying user control changes its FreqOne dependency property, I want TestFreqOne to change as well. I am trying to create a user control that will "output" a result to the parent control. How would I go about doing this? Thank you.
Your question title already suggests it. You need a two-way binding:
<spread:FreqSpreadUC FreqOne="{Binding TestFreqOne, Mode=TwoWay}" />
Alternatively you might register property metadata with your dependency property that makes it bind two-way by default:
public static readonly DependencyProperty FreqOneProperty =
DependencyProperty.Register(
"FreqOne", typeof(String), typeof(FreqSpreadUC)
new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
I created a User Control and in code behind, I added the following DP. When I switch to XAML and try to type the name of the property next to the UserControl tag, for example "Test", it doesn't show up. I wonder what could be missing here.
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof(String), typeof(UserControl1));
You also need to implement the CLR Wrapper for that property:
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
I have a custom text box defined as follows:
public class CustomTextBox : TextBox
{
public static DependencyProperty CustomTextProperty =
DependencyProperty.Register("CustomText", typeof(string),
typeof(CustomTextBox));
static CustomTextBox()
{
TextProperty.OverrideMetadata(typeof(SMSTextBox),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.Journal |
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(CustomTextBox_OnTextPropertyChanged));
}
public string CustomText
{
get { return (string)GetValue(CustomTextProperty); }
set { SetValue(CustomTextProperty, value); }
}
private static void CustomTextBox_OnTextPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
CustomTextBox customTextBox = d as CustomTextBox;
customTextBox.SetValue(CustomTextProperty, e.NewValue);
}
}
I'm binding the Custom Text property in the XAML -
<local:CustomTextBox CustomText="{Binding ViewModelProperty}" />
The problem I'm facing is that when I enter anything in the CustomTextBox, the changes are not reflected in the ViewModelProperty i.e. the ViewModelProperty is not getting updated. The CustomTextProperty is getting updated but I suppose I need to do something extra to make the binding work as well.
What am I not doing? I would appreciate any help regarding this.
Thank you
I guess the binding needs to be two-way.
<local:CustomTextBox
CustomText="{Binding ViewModelProperty, Mode=TwoWay}" />
You wouldn't need to specify the Mode if you made the CustomText property bind two-way by default:
public static readonly DependencyProperty CustomTextProperty =
DependencyProperty.Register(
"CustomText", typeof(string), typeof(CustomTextBox),
new FrameworkPropertyMetadata(
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
You may also have to define a PropertyChangedCallback for the CustomText property that updates the Text property (i.e. the other direction of what you have implemented now). Otherwise the TextBox won't display anything that is initially contained in the ViewModel property and of course woudln't be updated when the ViewModel property changes.