Dependency property type not respected - c#

Why can a dependency property with type XXX get a value of another type ?
Is the type of a dependency property just defined for the default value ?
For example:
Project structure:
User control code (CarControl):
XAML code:
<UserControl x:Class="TypeOfDependencyProperty.Controls.CarControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock Text="{Binding Brand}"/>
</Grid>
</UserControl>
Code behind (C#):
using System.Windows;
using System.Windows.Controls;
namespace TypeOfDependencyProperty.Controls
{
public partial class CarControl : UserControl
{
#region Brand
public static readonly DependencyProperty BrandProperty =
DependencyProperty.Register("Brand", typeof(string), typeof(CarControl),
new FrameworkPropertyMetadata((string)string.Empty));
public string Brand
{
get { return (string)GetValue(BrandProperty); }
set { SetValue(BrandProperty, value); }
}
#endregion
public CarControl()
{
InitializeComponent();
}
}
}
Note that this dependency property Brand is of type string here.
View code (CarView):
XAML code:
<Page x:Class="TypeOfDependencyProperty.Views.CarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:TypeOfDependencyProperty.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="CarView">
<Grid>
<controls:CarControl Brand="{Binding Brand}"/>
</Grid>
</Page>
Code behind (C#):
using System.Windows.Controls;
using TypeOfDependencyProperty.ViewModels;
namespace TypeOfDependencyProperty.Views
{
public partial class CarView : Page
{
public CarView()
{
InitializeComponent();
this.DataContext = new CarViewModel();
}
}
}
View model code (CarViewModel):
namespace TypeOfDependencyProperty.ViewModels
{
public class CarViewModel
{
public string Brand { get; set; }
public CarViewModel()
{
Brand = "XXXXXXXXXXXXXXXXXXXXXXXXX"; // Any value
}
}
}
Now, if I change the type from string to List<XXX> (or other) as below, it keeps working.
#region Brand
public static readonly DependencyProperty BrandProperty =
DependencyProperty.Register("Brand", typeof(List<double>), typeof(CarControl),
new FrameworkPropertyMetadata((List<double>)null));
public List<double>Brand
{
get { return (List<double>)GetValue(BrandProperty); }
set { SetValue(BrandProperty, value); }
}
#endregion
Of course, I obtain a following error in the output window but that still works ! The value is shown without failure when it's running.
System.Windows.Data Error: 1 : Cannot create default converter to
perform 'one-way' conversions between types 'System.String' and
'System.Collections.Generic.List1[System.Double]'. Consider using
Converter property of Binding. BindingExpression:Path=Brand;
DataItem='CarViewModel' (HashCode=14000148); target element is
'CarControl' (Name=''); target property is 'Brand' (type 'List1')
System.Windows.Data Error: 5 : Value produced by BindingExpression is
not valid for target property.; Value='Car brand'
BindingExpression:Path=Brand; DataItem='CarViewModel'
(HashCode=14000148); target element is 'CarControl' (Name=''); target
property is 'Brand' (type 'List`1')
Can somebody explain me? Is it a bug ?

The Binding in
<TextBlock Text="{Binding Brand}"/>
binds directy to the Brand property in the view model. It does not use the Brand property of the control.
So it would even show the view model property value when you write
<controls:CarControl />
without binding the control's Brand property at all.
The correct usage of the control's property in the control's XAML would be this:
<TextBlock Text="{Binding Brand,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>

When you say 'get a value'
in:
Why can a dependency property with type XXX get a value of another type ?
What you are asking about is really how a Binding is resolved.
The WPF framework resolves a binding and gets the actual current value.
When it is done resolving, the framework will try to 'set' the value for your dependency property, and only then will it check if the types are the same.
If they are not and no converter was supplied to the binding, it will throw this exception you added.

DependecyProperty type defines the type of data stored inside it.
You can bind to it only the same type of data. Or you can add a converter to binding. To do it you have to implement the interface IValueConverter.
But I don't understand your problem, want you to show entire list in a string? Or want you to create an item for each element of list?
In the second case I suggest you to use a ItemsControl and insert your custom control inside the ItemTemplate.
Finally you don't have to define default value every time, you can remove PropertyMetadata from DependecyProperty inizialization. And remember if you define it there it will be static and will change from others instances only with base types. If you have a class I suggest you to use null and assign it in the class Costructor.
public static readonly DependencyProperty BrandProperty =
DependencyProperty.Register("Brand", typeof(List<double>), typeof(CarControl));

Related

Create dependency property for WPF Window itself in its code behind xaml.cs

I have a WPF window which I have changed its borders, title bar and buttons for a custom one. Separately in a ResourceDictionary I have defined the Style that I want to apply to my WPF window.
Then I bind that style to my WPF Window using below line of code:
Style="{DynamicResource CustomWindowStyle}"
Please see all my code posted in another thread that I created to ask for other things. Refer to this thread to see the code (I want to avoid repeating here again).
Now what I am trying to do is to create some custom properties (MyCustomProperty01, MyCustomProperty02) to that WPF Window, some like below:
myDialogView.xaml:
<Window x:Class="myApp.Views.myDialogView"
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:v="clr-namespace:myApp.Views"
xmlns:vm="clr-namespace:myApp.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Style="{StaticResource CustomWindowStyle}"
WindowStyle="None"
MyCustomProperty01 = "true"
MyCustomProperty02 = "true">
...and then in the code-behind of this WPF window (xaml.cs) I want to define those dependency properties MyCustomProperty01 and MyCustomProperty02, the ones you see above in the code snippet for the Window.
So I create those dependency properties in the code-behind as below.
myDialogView.xaml.cs (code-behind):
namespace myApp.Views
{
public partial class myDialogView: Window
{
public myDialogView()
{
InitializeComponent();
}
public static readonly DependencyProperty MyCustomProperty01Property =
DependencyProperty.Register("MyCustomProperty01",
typeof(bool),
typeof(myDialogView),
new FrameworkPropertyMetadata(false));
public bool MyCustomProperty01
{
get => (bool)GetValue(MyCustomProperty01Property );
set => SetValue(MyCustomProperty01Property , value);
}
public static readonly DependencyProperty MyCustomProperty02Property =
DependencyProperty.Register("MyCustomProperty02",
typeof(bool),
typeof(myDialogView),
new FrameworkPropertyMetadata(false));
public bool MyCustomProperty02
{
get => (bool)GetValue(MyCustomProperty02Property );
set => SetValue(MyCustomProperty02Property , value);
}
}
}
So when I start typing these dependency properties MyCustomProperty01 and MyCustomProperty01 for the window in the xaml view, intellisense looks like it is not recognizing those dependency properties. So what am I doing wrong? Could some tell me how I can achieve this with some code snippet?
You need to registerattached for this to work.
I'm not 100% sure why, I just know it won't work with the usual dependency property.
I think it's because it's in a window tag and it's "really" a myDialogView causes the issue.
Here's an example attached property I have:
public static readonly DependencyProperty TakeMapPictureProperty =
DependencyProperty.RegisterAttached(
"TakeMapPicture",
typeof(bool),
typeof(MainWindow),
new FrameworkPropertyMetadata(false
, new PropertyChangedCallback(TakeMapPictureChanged)
));
private static async void TakeMapPictureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
public static void SetTakeMapPicture(UIElement element, bool value)
{
element.SetValue(TakeMapPictureProperty, value);
}
public static bool GetTakeMapPicture(UIElement element)
{
return (bool)element.GetValue(TakeMapPictureProperty);
}
And in the window tag
local:MainWindow.TakeMapPicture="{Binding CaptureMap}"
Where you might want to use the one dependency property in several user controls or windows, you can define the attached properties in a separate class. There are a couple of ways to do this but the one I prefer looks like:
public class MainWin : DependencyObject
{
public static readonly DependencyProperty MapFileProperty = DependencyProperty.RegisterAttached(
"MapFile",
typeof(string),
typeof(MainWin),
new FrameworkPropertyMetadata(string.Empty
, new PropertyChangedCallback(MapFileChanged)
));
And that is used inside a window tag:
local:MainWin.MapFile="{Binding Path=MapFile}"
You are trying to set the property on the wrong element (locally/attribute syntax):
<Window ... MyCustomProperty01="True" />
Of course, Window does not have a MyCustomProperty01 property.
But myDialogView has this property.
To set this property, either use a Style:
<Window>
<Window.Resources>
<Style TargetType="myDialogView">
<Setter Property="MyCustomProperty01" Value="True" />
</Style>
</Window.Resources>
</Window>
Or set it locally on the proper myDialogView element. But you would have to create a derived type (e.g., myExtendedDialogView), so that you can define myDialogView (the base type) as the root element.
Note how the root element is always the base type of the actual extending type: for example <Window /> of MainWindow or <UserControl /> of MyUserControl or <Page /> of MyPage or <Application /> of App.
Specify the partial class (the derived type that provides the code-behind file) using the x:Class directive on the root element:
<myDialogView x:Class="myExtendedDialogView"
MyCustomProperty01="True">
</myDialogView >
// Define the extended class as partial (with code-behind)
// and the base class that contains the custom properties as a simple class (no code-behind)
partial class myExtendedDialogView : myDialogView
{
public myExtendedDialogView() => InitializeComponent();
}
// Base class used as XAML root element.
// This type has no code-behind file (not partial)
class myDialogView : Window
{
// Dependency properties
}

DependencyProperty Silverlight UserControl

I have read through a few articles on this and I can't see what im doing wrong here could anyone help :)
I have a UserControl called CreateRuleItemView I want to add a Dependency Property on here that I can bind my ViewModel too. So far I have.
public partial class CreateRuleItemView : UserControl
{
public CreateRuleItemView()
{
InitializeComponent();
}
public Boolean ShowEditTablePopup
{
get
{
return (Boolean)this.GetValue(ShowEditTablePopupProperty);
}
set
{
this.SetValue(ShowEditTablePopupProperty, value);
}
}
public static readonly DependencyProperty ShowEditTablePopupProperty = DependencyProperty.Register("ShowEditTablePopup", typeof(Boolean), typeof(CreateRuleItemView), new PropertyMetadata(null, OnShowEditTablePopupChanged));
private static void OnShowEditTablePopupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
}
}
If I then try to access the property in the User Control Xaml I get:
<UserControl x:Class="Views.Setup.CreateRuleItemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance Type=vm:CreateRuleItemViewModel, IsDesignTimeCreatable=False}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" ShowEditTablePopup="{Binding DataContext.ShowEditTablePopup}" >
Error 1 The member "ShowEditTablePopup" is not recognized or is not accessible.
Error 3 The property 'ShowEditTablePopup' does not exist on the type 'UserControl'
Error 2 The property 'ShowEditTablePopup' was not found in type 'UserControl'.
Edit 1:
Ok Managed to get around this by adding the binding in the code behind on my Main window where i setup my view.
Setup.CreateRuleItemView v = new Setup.CreateRuleItemView();
BindingOperations.SetBinding(v, CreateRuleItemView.EditTablePopupProperty, new Binding("EditTablePopup"));
You won't be able to achieve this with a UserControl (I've just tried replacing the <UserControl... partial declaration in XAML with <local:CreateRuleItemView when recreating the code locally, but this results in a circular reference and thus won't compile/will potentially result in a XamlParseException). I'd write a control inheriting from ContentControl to which you can add the property and template it instead (I did this with WPF so the namespaces may differ, otherwise the code will work):
using System;
using System.Windows;
using System.Windows.Controls;
namespace DepPropTest
{
/// <summary>
/// Description of CreateRuleItemView.
/// </summary>
public class CreateRuleItemView : ContentControl
{
public CreateRuleItemView()
{
}
public static readonly DependencyProperty ShowEditTablePopupProperty =
DependencyProperty.Register("ShowEditTablePopup", typeof (bool), typeof (CreateRuleItemView), new PropertyMetadata());
public bool ShowEditTablePopup
{
get { return (bool) GetValue(ShowEditTablePopupProperty); }
set { SetValue(ShowEditTablePopupProperty, value); }
}
}
}
Then you can use it as follows (this example uses WPF by the way, hence Window being the parent control):
<Window x:Class="DepPropTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DepPropTest"
Title="DepPropTest" Height="300" Width="300">
<local:CreateRuleItemView Width="300"
Height="300"
ShowEditTablePopup="True">
<local:CreateRuleItemView.Template>
<ControlTemplate>
<!-- define your control's visual appearance... -->
</ControlTemplate>
</local:CreateRuleItemView.Template>
<TextBox Text="Some content for your view" />
</local:CreateRuleItemView>
</Window>

Loading XAML to C# for Data Binding

Ok, we are trying out XAML for our GUI now (and learning as we go)...I have been able to do the data binding without a problem in XAML and C# independent of one another, but now comes the time I need to pass values back and forth and I'm a bit lost. When I compile and try to navigate to the page, it is throwing a XamlParseException: Specified class name doesn't match actual root instance type. Remove Class directive or provide an instance via XamlObjectWriterSettings.RootObjectInstance. Line 5 position 2.
Any help or a gentle shove in the right direction is greatly appreciated :)
Here's where I am:
namespace TheAirline.GraphicsModel.PageModel.PageFinancesModel
{
/// <summary>
/// Interaction logic for PageFinances.xaml
/// </summary>
public partial class PageFinances : Page
{
private Airline Airline;
public PageFinances(Airline airline)
{
InitializeComponent();
this.Language = XmlLanguage.GetLanguage(new CultureInfo(AppSettings.GetInstance().getLanguage().CultureInfo, true).IetfLanguageTag);
this.Airline = airline;
Page page = null;
//loading the XAML
using (FileStream fs = new FileStream("TheAirline\\GraphicsModel\\PageModel \\PageFinancesModel\\PageFinances.xaml", FileMode.Open, FileAccess.Read))
{
page = (Page)XamlReader.Load(fs);
}
//finding XAML element and trying to set the value to a variable
string airlineCash = GameObject.GetInstance().HumanAirline.Money.ToString();
TextBox cashValue = (TextBox)page.FindName("cashValue");
cashValue.DataContext = airlineCash;
}
}
}
And the first few lines of the XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:AirlineModel="clr-namespace:TheAirline.Model.AirlineModel"
mc:Ignorable="d"
x:Class="TheAirline.GraphicsModel.PageModel.PageFinancesModel.PageFinances"
xmlns:c="clr-namespace:TheAirline.GraphicsModel.Converters"
...>
</Page>
Bindings in XAML are resolved against the object that is assigned to the DataContext property of any given XAML element. The value of that property (as well as many other properties) Is Inherited in any given Visual Tree from parent elements to child elements.
for instance, given this class:
public namespace MyNamespace
{
public class ViewModel
{
public string Name {get;set;}
public bool IsActive {get;set;}
}
}
and this XAML:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
FontSize="20">
<Window.DataContext>
<local:ViewModel>
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding Path=Name}"/>
<CheckBox IsChecked="{Binding Path=IsActive}"/>
<StackPanel>
</Window>
All four objects defined in XAML, the Window, the StackPanel, the TextBox, and the CheckBox, will have a FontSize of 20, and the instance of the ViewModel class assigned to their DataContext property. Therefore all bindings (Except bindings with a specified ElementName, RelativeSource, or Source) will be resolved against that instance.
It would be exactly the same if the property was assigned in code instead of in XAML:
public MyWindow() //Window Constructor
{
InitializeComponent();
this.DataContext = new ViewModel(); //Note that keyword "this" is redundant, I just explicity put it there for clarity.
}
Because of this, there is no need to set the DataContext property to each element explicitly, as the framework is already taking care of that.
Also, notice that in XAML, most built-in Markup Extensions have a default constructor convention that allows you to abbreviate their usage. In the case of the Binding Markup Extension, the default constructor has the Path property, therefore this:
<TextBox Text="{Binding Path=Name}"/>
is exactly the same as this:
<TextBox Text="{Binding Name}"/>
Now, for property changes in the underlying DataContext to be automatically passed from the binding source (ViewModel) to the binding target (XAML-defined objects), the source object must implement the System.ComponentModel.INotifyPropertyChanged interface and raise the PropertyChanged event every time a property changes.
Therefore, in order to support Two-Way Binding, the example class should look like this:
public namespace MyNamespace
{
public class ViewModel: INotifyPropertyChanged
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
private bool _isActive;
public bool IsActive
{
get
{
return _isActive;
}
set
{
_isActive = value;
NotifyPropertyChanged("IsActive");
}
}
}
public void NotifyPropertyChanged (string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
}
}
Notice that the ViewModel class has no dependency or direct reference to any of the XAML-defined objects, but still it contains the Values of the properties that will appear in the UI. This allows for a complete decoupling between UI and application logic/data known as the MVVM Pattern. I strongly suggest you research on that topic if you expect to be successful in programming in C# + XAML, because it is a radical mindshift when compared to other, traditional UI paradigms.
For example, something like this is not recommended in XAML-based applications:
if (myWindow.CheckBox1.IsChecked)
//Do Something
because that would mean that you're coupling the application logic and making it dependant on the state of UI elements, which is precisely what you need to avoid.
Notice that all the links and all the concepts referenced in this answer pertain to WPF, but are also applicable to Silverlight and WinRT. Since you did not specify which of the three XAML-based frameworks you're using, I posted the WPF ones, which is what I'm most familiar with.

What do I need to further qualify the DataContext for a binding?

The files I have created and will be referring to in this question are:
TechnicainSelectionView.xaml
TechnicianSelectionView.cs
TechnicianSelectionViewModel.cs
Technician.cs (Code First Entity)
I have the following xaml in my TechnicanSelectionView.xaml
<UserControl xmlns etc... here"
d:DesignHeight="48" d:DesignWidth="300">
<Grid>
<StackPanel>
<Label Content="Select a Technican to run the test" FontWeight="Bold"></Label>
<ComboBox ItemsSource="{Binding Technicians, Mode=TwoWay}"></ComboBox>
</StackPanel>
</Grid>
</UserControl>
The Technicians property to which the ItemSource is set to bind to states that it Cannot resolve Technicians due to an unknown DataContext.
So if we look to my TechnicianSelectionView.cs code-behind...
public partial class TechnicianSelectionView : UserControl
{
public TechnicianSelectionViewModel ViewModel { get; private set; }
public TechnicianSelectionView()
{
InitializeComponent();
Technician.GenerateSeedData();
ViewModel = new TechnicianSelectionViewModel();
DataContext = ViewModel;
}
}
... we see that I am setting the view's DataContext to my TechnicianSelectionViewModel ...
public class TechnicianSelectionViewModel : ViewModelBase
{
public ObservableCollection<Technician> Technicians { get; set; }
public TechnicianSelectionViewModel()
{
Technicians = new ObservableCollection<Technician>();
}
public bool IsLoaded { get; private set; }
public void LoadTechnicians()
{
List<Technician> technicians;
using (var db = new TestContext())
{
var query = from tech in db.Technicians
select tech;
foreach (var technician in query)
{
Technicians.Add(technician);
}
}
IsLoaded = true;
}
}
Techicians is a property on my ViewModel...
So having already set the DataContext for the view, why can't it resolve Technicians on the ViewModel as the DataContext/property it is going to bind to?
EDIT:
As per a concern in a comment below. This is a design time problem and not compile time. I should have indicated this at the start.
You need to specify the type of data context in the xaml to get design-time support. Even though you assigned the data context in code-behind, the designer is not going to recognize that.
Try putting the following in your xaml:
d:DataContext="{d:DesignInstance vm:TechnicianSelectionViewModel}"
See this link for more details.
In my Xamarin Forms Xaml file I used the following lines in the header (ContentPage tag) and it worked perfectly as I wanted.
Basically now
the intellisense shows the fields in the binding
my Resharper is able to rename the binding in the Xaml file if I refactor the name of the property
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:YourApplicationName.ViewModels;assembly=YourApplicationName"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance {x:Type vm:CurrentPageViewModel}}"

How to bind a property from my usercontrol content control to a property in my viewmodel?

I have a usercontrol like this:
<UserControl x:Class="MySample.customtextbox"
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"
mc:Ignorable="d"
d:DesignHeight="20" d:DesignWidth="300">
<Grid>
<TextBox x:Name="Ytextbox" Background="Yellow"/>
</Grid>
</UserControl>
I want use this control in a View such as MainWindowView
How can I Binde my Ytextbox Text Property to a property in my MainWindowViewModel?
<CT:customtextbox Text="{binding mypropertyinviewmodel}"/>
I know that I must define a DependencyProperty for my control until I can bind a property in my viewmodel to it so i define a dependency property for my control like this:
public static readonly DependencyProperty InfoTextProperty =
DependencyProperty.Register("InfoText", typeof(string), typeof(customtextbox), new FrameworkPropertyMetadata(false));
public string InfoText
{
get { return (string)GetValue(InfoTextProperty);}
set
{
SetValue(InfoTextProperty, value);
}
}
When I define a dependency property for my control I have a xaml error:
Error 1 Cannot create an instance of "customtextbox".
new FrameworkPropertyMetadata(false)
You cannot set the default value of a string property to false (which of course is a bool).
There may be some other problems (e.g. you have no binding on the TextBox in the user coontrol declaration and you try to set a property you did not register where you create an instance) but for those you should search SO.
You're trying to set boolean value to a string DependencyProperty. Should be something like that
new FrameworkPropertyMetadata(string.Empty)
or
new FrameworkPropertyMetadata(null)
Umm try this as the code for your dependency property.
public static readonly DependencyProperty InfoTextProperty =
DependencyProperty.Register(
"InfoText",
typeof(string),
typeof(customtextbox)
);
public string InfoText
{
get { return (string)GetValue(InfoTextProperty);}
set {SetValue(InfoTextProperty, value); }
}
I just removed the last parameter from when you register the property, I think that's supposed to provide a default value for the property and you were providing a boolean instead of a string, it's an optional parameter anyways.

Categories