Currently, I am refactoring an application, where we have lots of duplicated XAML code. I want to use custom UserControls instead. I did a tutorial, on how to create those, but now I am at a point, where I do not know how to solve it.
So, currently I am getting this error:
System.Windows.Markup.XamlParseException: '"Binding" cannot be set for the "PropertyMargin" property of type "TxtInput". "Binding" can only be set for a "DependencyProperty" of a "DependencyObject"
So, basically, I have a custom UserControl:
<UserControl ...>
<UserControl.Resources>
...
</UserControl.Resources>
<DockPanel Margin="{Binding PropertyMargin}">
<md:Card Style="{StaticResource ParamCard}">
<TextBlock Text="{Binding PropertyName}"/>
</md:Card>
</DockPanel>
</UserControl>
With its Code-Behind:
public partial class TxtInput : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
#region Properties
private string _propertyName = string.Empty;
public string PropertyName
{
get { return _propertyName; }
set
{
_propertyName = value;
OnPropertyChanged();
}
}
private string _propertyMargin = "0, 0, 0, 0";
public string PropertyMargin
{
get { return _propertyMargin; }
set
{
_propertyMargin = value;
OnPropertyChanged();
}
}
#endregion
public TxtInput()
{
DataContext = this;
InitializeComponent();
}
private void OnPropertyChanged([CallerMemberName] string? property = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
I use this UserControl within another one – and I want to inject the Properties via the “Parent one”
So – for statically set properties, e.g. the PropertyName – that’s no problem at all – but for dynamically changing values, for example the ProprtyMargin, it does not work as expected:
“Parent-UserControl”
<uc:TxtInput PropertyName="Developer Name" PropertyMargin="{Binding NameMargin}"/>
The Margin changes, depending, if the validation within the parent-userControl is successful or not (just an example here)
Parent-UserControlViewModel
...
private string _nameMargin;
public string NameMargin
{
get { return _nameMargin; }
set { SetProperty(ref _nameMargin, value); }
}
...
private void SetErrorTxts(List<ValidationFailure> errors)
{
RemoveErrorTxtsFromProperties();
foreach (var _ in errors.Select(error => error.ErrorMessage).Where(error => error.Contains("Name")).Select(error => new { }))
{
// ------------------------------
// Default values for properties
// if set not correctly
// ------------------------------
NameMargin = "0 0 0 16";
}
}
// ------------------------------
// Default values for properties
// if set correctly
// ------------------------------
private void RemoveErrorTxtsFromProperties()
{
NameMargin = "0 0 0 8";
}
I know, it’s possible if I set the UserControl’s DataContext to the ViewModel of the Control, where I am using it – but I want to use my custom control in different other views as well, so I cannot set the DataContext of this UserControl statically.
Basically, I want the custom UserControl represent the “style” that it gets via the properties from the parent-ViewModel. I hope it’s clear, what I mean.
Any tip would be helpful!
06luki06 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.