Apologies if someone can find an already answered question that works for this, I've been digging around for 4 hours and I don't know if my search criteria is wrong, or if I'm going insane.
I am working on an MVVM project with custom controls. My custom controls will pull in whatever is already in the ViewModel when it loads, but it will not let me update the value via the interface. I've tried a couple different solutions and at this point my head is spinning. Below is my code.
If you need the code for my view model, please let me know. It's just a basic getter and setter so I only included the relevant code for the control and its usage.
TitledTextBox.cs:
public class TitledTextBox : Control
{
public static DependencyProperty TextLabelProperty = DependencyProperty.Register("TextLabel", typeof(string), typeof(TitledTextBox));
public static DependencyProperty TextValueProperty = DependencyProperty.Register("TextValue", typeof(string), typeof(TitledTextBox));
static TitledTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TitledTextBox), new FrameworkPropertyMetadata(typeof(TitledTextBox)));
}
public string TextLabel
{
get { return (string)GetValue(TextLabelProperty); }
set { SetValue(TextLabelProperty, value); }
}
public string TextValue
{
get { return (string)GetValue(TextValueProperty); }
set { SetValue(TextValueProperty, value); }
}
}
Generic.xaml:
<Style TargetType="{x:Type local:TitledTextBox}" >
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TitledTextBox}">
<Grid Visibility="{TemplateBinding Visibility}">
<Rectangle Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<TextBox Text="{TemplateBinding TextValue}" FontSize="11" BorderThickness="0" Margin="2,10,2,2" Background="Transparent" TextWrapping="Wrap" />
<Label Content="{TemplateBinding TextLabel}" FontWeight="Bold" FontSize="8.0" Foreground="Black" VerticalAlignment="Top" Margin="0,-5,0,2"/>
<Border BorderBrush="Gray" BorderThickness="0.8,0.8,0,0" Margin="0" CornerRadius="3"/>
<Border BorderBrush="DimGray" BorderThickness="0,0,0.8,0.8" Margin="0" CornerRadius="3" >
<Border.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="5" Color="DimGray"/>
</Border.Effect>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the usage in my TicketWindow.xaml:
xmlns:ctrl="clr-namespace:PIUS.MOPOCommunicationTool.Controls"
<ctrl:TitledTextBox Grid.Row="1" Grid.Column="2" Margin="2" TextLabel="CUSTOMER" TextValue="{Binding Ticket.Customer, UpdateSourceTrigger=PropertyChanged}"/>
If I check the Live Property Explorer, I can see that the binding on the TextBox in the custom control is evaluating correctly, but the TextValue of the TitledTextBox and the property in my ViewModel are not updating.
I've tried doing a PropertyChangedCallback like below, but that didn't work. It fires when the window loads in, but it doesn't fire when I change the value in the UI.
public static DependencyProperty TextValueProperty = DependencyProperty.Register("TextValue", typeof(string), typeof(TitledTextBox)
, new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(TitledTextBox_OnTextPropertyChanged)));
private static void TitledTextBox_OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
TitledTextBox box = sender as TitledTextBox;
box.SetValue(TextValueProperty, e.NewValue);
}
I've tried fiddling with the TemplateBinding v. Binding and got nowhere with that either. I feel like I'm missing something incredibly simple here.