I have a control where i want to add CharacterCasing since it doesn't support it by default.
I added a custom dependency property called "CharacterCasing".
Now when i use it in xaml i want to have the options just like in the normal TextBox:
Any ideas how to implement the suggestion list in the dependency property?
This is my code in xaml:
<TestControl:APTextBox CharacterCasing="UpperCase" Text="{Binding AktuelleZeile.LKR, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}">
And this is the dependency property:
public static readonly DependencyProperty CharacterCasingProperty =
DependencyProperty.Register(name: "CharacterCasing",
propertyType: typeof(string),
ownerType: typeof(APTextBox),
typeMetadata: new PropertyMetadata("Normal"));
public string CharacterCasing
{
get { return (string)this.GetValue(CharacterCasingProperty); }
set { this.SetValue(CharacterCasingProperty, value); }
}
Because you define it as string. Change the string with CharacterCasing or which kind of enum you want to use.
public static readonly DependencyProperty CharacterCasingProperty =
DependencyProperty.Register(name: "CharacterCasing",
propertyType: typeof(CharacterCasing),
ownerType: typeof(APTextBox),
typeMetadata: new PropertyMetadata(CharacterCasing.Normal));
public CharacterCasing CharacterCasing
{
get { return (CharacterCasing)this.GetValue(CharacterCasingProperty); }
set { this.SetValue(CharacterCasingProperty, value); }
}
Related
I am new to binding. I have binded slider value to my control's property and my controls property get changed when I change the slider value.
Now, when I need to change the slider value by changing my property value, it does not work..
I modified the xaml from some internet source, but still not get the expected output.
can anyone help me out...
<Grid>
<cc:MyControl Name="mycntrl" ZoomPercentage="{Binding ElementName=slider,Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></cc:MyControl>
<Slider Name="slider" Margin="20,20,20,400" Minimum="100" Maximum="400"></Slider>
</Grid>
Updated:
My code behind for my ZoomPercentage dependency property is below
public double ZoomPercentage
{
get
{
return (double)GetValue(ZoomPercentageProperty);
}
set
{
SetValue(ZoomPercentageProperty, value);
}
}
My dependency registration
public static readonly DependencyProperty ZoomPercentageProperty = DependencyProperty.Register("ZoomPercentage", typeof(double), typeof(MyControl), new FrameworkPropertyMetadata(ZoomPercentagePropertyChanged));
public static void ZoomPercentagePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (args.OldValue != null)
{
if ((double)args.NewValue != (double)args.OldValue)
{
MyControl mycontrol = obj as MyControl;
mycontrol .ZoomTo((int)((double)args.NewValue));
}
}
}
Your ZoomPercentage property should be implemented as a Dependencyproperty
Something like this
public class MyControl:UserControl
{
public MyControl() : base() { }
public double ZoomPercentage
{
get { return (double)this.GetValue(ZoomPercentageProperty); }
set { this.SetValue(ZoomPercentageProperty, value); }
}
public static readonly DependencyProperty ZoomPercentageProperty = DependencyProperty.Register(
"ZoomPercentage", typeof(double), typeof(MyControl:),new PropertyMetadata(0));
}
read more here
If you want a data bound control in the UI to update after changes made in code then you have to do one of two things. One option is to correctly implement the INotifyPropertyChanged interface in the class that you declared your Value property.
The other is to declare your Value property as a DependencyProperty, although you should only really do this in the code behind of your Window or UserControl and opt for the first method if you are using a view model. The purpose of these two methods is for you to 'plug in' to WPF notification framework, so that your UI control will update. Please read the linked pages for more information.
MyControl.xaml.cs
public string achName
{
get { return (string)this.GetValue(achNameProperty); }
set { this.SetValue(achNameProperty, value); }
}
public static readonly DependencyProperty achNameProperty = DependencyProperty.Register("achName", typeof(string), typeof(MyControl), new PropertyMetadata(null));
MainPage.xaml
<My:MyControl achName="{Binding Name}"/>
name has a value, but it doesn't seem to get send to the dependendcy (achName) property. How can I fix this?
ViewModel
public string Name { get { return "some random test value"; } }
other bindings to viewmodel do work, so the problem doesn't lie there.
The only reason i can see is that Binding to Name is failing. You can debug your bindings to see if its not failing. Refer to this - Debug Data Bindings
I created a custom controll in expression Blend and added a property. I found the property in Blend, but the option for create a databinding isn't available. What do I have to make that I can add databindings through Blend?
Code Property:
public string TileText
{
get { return this.labelTileText.Text; }
set { this.labelTileText.Text = value; }
}
If you want to enable databinding on a property of a custom control, you need to create a dependency property for that property.
The property:
public string TileText {
get { return this.labelTileText.Text; }
set { this.labelTileText.Text = value; }
}
Dependency property:
public static readonly DependencyProperty TileTextProperty = DependencyProperty.Register(
"TileText", typeof(String), typeof(ClassName), new UIPropertyMetadata("default value", callBack));
And then you should implement that callBack function that to be called whenever 'TileText' property is changed.
Trying to create my own custom AttachedProperty for a WPF DependencyObject failed to actually do what I wanted it to do, and I am a bit worried that I (again) did not understand a WPF concept fully.
I made a very simple test class to show where my problem lies. From the MSDN Documentation, I copied
public class TestBox : TextBox
{
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
"IsBubbleSource",
typeof(Boolean),
typeof(TestBox)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
return (Boolean)element.GetValue(IsBubbleSourceProperty);
}
public Boolean IsBubbleSource
{
get
{
return (Boolean)GetValue(IsBubbleSourceProperty);
}
set
{
SetValue(IsBubbleSourceProperty, value);
}
}
}
Now, placing my new and funky TextBox into a Grid like this
<Grid vbs:TestBox.IsBubbleSource="true">
<vbs:TestBox x:Name="Test" Text="Test" >
</vbs:TestBox>
</Grid>
I expected every child that does not set the IsBubbleSource property itself to "inherit" it from its parent grid. It does not do this; a MessageBox.Show(Test.IsBubbleSource.ToString()) shows "false". The attached property is set to true. I checked this using an OnPropertyChanged event handler. Did I miss something?
Thanks!
By default, attached properties are not inherited. You have to specify it when you define the property:
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
"IsBubbleSource",
typeof(Boolean),
typeof(TestBox),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits)
);
I have a xaml view like this:
<Tv:TvPanel
xmlns:Tv="...">
<Tv:TvPanel.Resources>
<Tv:Parameters x:Key="parameterList">
<Tv:ParameterDefinition ParameterName="MyParam" InitialValue="123abc">
<Tv:ValueBinding Value="{Binding ElementName=myTextBox, Path=Text}"/>
</Tv:ParameterDefinition>
</Tv:Parameters>
<Tv:TvXmlDataProvider x:Key="dataProvider"
Source="http://server/myXml.xml"
Parameters="{StaticResource parameterList}"/>
</Tv:TvPanel.Resources>
<Tv:TvPage DataContext="{StaticResource dataProvider}" >
<Tv:TvText x:Name="myTextBox"
Tv:TvPage.Left="360" Tv:TvPage.Top="10"
Height="30" Width="200"/>
<Tv:TvButton Tv:TvPage.Left="560" Tv:TvPage.Top="10"
Content="Search"/>
/*SOME MORE CODE */
all the controls extending some standard wpf controls (canvas, label, ...).
The classes Parameters, ParameterDefinition & ValueBinding look like this:
[ContentProperty("ParameterDefinitions")]
public class Parameters
{
private readonly List<ParameterDefinition> parameterDefinitions = new List<ParameterDefinition>();
public List<ParameterDefinition> ParameterDefinitions { get { return parameterDefinitions; } }
}
[ContentProperty("ValueBindings")]
public class ParameterDefinition : DependencyObject
{
public static DependencyProperty ParameterNameProperty = DependencyProperty.Register("ParameterName", typeof (string), typeof (ParameterDefinition), new PropertyMetadata(""));
public string ParameterName
{
get { return (string) this.GetValue(ParameterNameProperty); }
set{ this.SetValue(ParameterNameProperty, value);}
}
public static DependencyProperty InitialValueProperty = DependencyProperty.Register("InitialValue", typeof(object), typeof(ParameterDefinition), new PropertyMetadata(new object()));
public object InitialValue
{
get { return this.GetValue(InitialValueProperty); }
set { this.SetValue(InitialValueProperty, value); }
}
private readonly List<ValueBinding> valueBindings = new List<ValueBinding>();
public List<ValueBinding> ValueBindings { get { return this.valueBindings; } }
}
public class ValueBinding : DependencyObject
{
public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(ValueBinding), new PropertyMetadata(""));
public string Value
{
get { return (string)this.GetValue(ValueProperty); }
set { this.SetValue(ValueProperty, value); }
}
}
The problem is that the databinding
Value="{Binding ElementName=myTextBox, Path=Text}"
not works in ValueBinding (Value is never set, has always the default value (and actions are performed to change the value)). The StaticResource binding in the dataprovider works perfectly, and element-to-element binding under the UIElements also works perfectly.
It compiles, and it seems there's no problem with the scope of elementname in the resourcedictionary.
What did i miss?
Edit1:
I forgot to mention the output of the VS-Console:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Text; DataItem=null; target element is 'ValueBinding' (HashCode=14342221); target property is 'Value' (type 'String')
In the TvPanel the DataContext is set to this.
I tried to derive from Freezable, instead of DependencyObject ==> same Problem.
I also tried to bind this way:
<Tv:ValueBinding>
<Tv:ValueBinding.Value>
<Binding ElementName="SearchText" Path="Text"/>
</Tv:ValueBinding.Value>
</Tv:ValueBinding>
but no difference.
I think that your class should derive from Freezable, otherwise there's no inheritance context: the DataContext is not propagated and the bindings don't work. See this article for more information.