Hi and thanks for your attention. (I apologize for editing the question so much and forgetting to properly proof read it first)
I am currently trying to develop a new WPF custom control that contains a small Plus button inside a text field for adding new items, to replace separate button and textboxes in the UI. Sounds simple enough but no matter how much I try I seem to not get the Data Bindings right.
The application is supposed to work with user entering a name in the textbox of my user control, and then the button of user control fires the AddCommand when button binded to add command inside my custom control is pressed then method attached to AddCommand handle the rest.
Generally I don't get an error and the problem is that due to some codes in other parts of application if the "textbox" I had binded to a Field(here for instance is: NewPsCondition.Name) is empty(or in this case not properly binded) the application won't allow me to actually fire AddCommand(by deactivating the button 'correctly' binded to AddCommand). However I always get an error when I try to fire AddCommand from my own custom control's button and if I try to set NewPsCondition.Name in textbox of my own control and fire the AddCommand on another button, that said button will be de-active. Further suggesting that I am not doing the binding right.
So far I tried all the other answers I found on Stackoverflow and google such as:
- adding
this.DataContext = this;
to custom user control constructor. - adding
RootElement.DataContext = this
to custom user control constructor. - making sure to have "Mode=TwoWay" where I call my user control.
- making sure the problem is actually with the custom user control by testing everything as it is but with separate button and textbox as was before.
this is an example of one of the places that I should call my control and how I am calling it now:
<StackPanel Orientation="Horizontal" >
<Label Content="نام"></Label>
<!--These bindings don't work-->
<control:AddFieldMV Margin="35px 0" Width="132px" SubmitCommand="{Binding Path=AddCommand}" InputText="{Binding Path=NewPsCondition.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<!--These bindings do-->
<Button Content="اضافه" Command="{Binding Path=AddCommand}" Click="ButtonBase_OnClick"></Button>
<TextBox Text="{Binding Path=NewPsCondition.Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Width="60px" Margin="40px 0"></TextBox>
</StackPanel>
This is the xaml code of my custom control:
<UserControl x:Class="TestInstrumentApplication.ResourceDictionary.Control.AddFieldMV"
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:local="clr-namespace:TestInstrumentApplication.ResourceDictionary.Control"
mc:Ignorable="d"
DataContext="this"
MinHeight="20px" MinWidth="70px">
<Grid x:Name="RootElement">
<Border
BorderBrush="#6D6E71"
BorderThickness="0 0 0 1"
CornerRadius="0">
<Grid MinHeight="20" Background="#F1F2F2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="15"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox MinWidth="50" Grid.Column="0" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent" Text="{Binding Path=InputText}">
</TextBox>
<Button Grid.Column="1" Height="20px" BorderBrush="Transparent" Click="AddButton_OnClick">
<Button.Background>
<VisualBrush >
<VisualBrush.Visual>
<Canvas Width="14.250" Height="14.250">
<!--there were some working vector graphics here that I removed to keep it short--> </Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Button.Background>
</Button>
</Grid>
</Border>
</Grid>
</UserControl>
and finally these are the custom control's C# code behind xaml code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TestInstrumentApplication.Utility;
namespace TestInstrumentApplication.ResourceDictionary.Control
{
/// <summary>
/// Interaction logic for AddFieldMV.xaml
/// </summary>
public partial class AddFieldMV : UserControl
{
public AddFieldMV()
{
InitializeComponent();
RootElement.DataContext = this;
}
public event EventHandler AddButtonClicked;
protected virtual void OnAddButtonClicked(EventArgs e)
{
AddButtonClicked?.Invoke(this, e);
}
private void AddButton_OnClick(object sender, RoutedEventArgs e)
{
OnAddButtonClicked(e);
//here I get a bug when I hit button on running application telling me SubmitCommand is null
SubmitCommand.Execute(sender);
}
public static readonly DependencyProperty SubmitCommandProperty
= DependencyProperty.Register(
"SubmitCommand",
typeof(ICommand),
typeof(AddFieldMV));
public ICommand SubmitCommand
{
get => (ICommand)GetValue(SubmitCommandProperty);
set => SetValue(SubmitCommandProperty, value);
}
public static readonly DependencyProperty InputTextProperty
= DependencyProperty.Register(
"InputText",
typeof(string),
typeof(AddFieldMV),
new PropertyMetadata(default(string)));
public string InputText
{
get
{
return (string)GetValue(InputTextProperty);
}
set { SetValue(InputTextProperty, value); }
}
private static void CustomTextBox_OnTextPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
AddFieldMV customTextBox = d as AddFieldMV;
customTextBox.SetValue(InputTextProperty, e.NewValue);
}
}
}