Regis
Regis

Reputation: 475

MVVM textbox in usercontrol bind to different types

I am using a usercontrol inside a grid. This usercontrol contains a textbox that is bound a property of an object supplied by the viewmodel. My problem is the property can be rather a string or a int.

I set the dependency property to be a string so it's working fine for displaying but if the user enters a string into a int field, no validation error is thrown by the view model but of course i can't save to the database.

usercontrol XAML

<UserControl x:Class="GenericFileTransferClient.Views.UserControlTextBox"
             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="300" d:DesignWidth="300">
    <Grid Name="GridLayout">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="7*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Path=LabelText}" VerticalAlignment="Center" Style="{StaticResource ResourceKey=TextBlockWrapping}" />
        <DockPanel Grid.Column="1">
            <Border DockPanel.Dock="Right"
                                ToolTip="" Style="{StaticResource BorderReportDetail}">
                <TextBlock Text="?" Style="{StaticResource TextBoxReportDetail}"></TextBlock>
            </Border>
            <TextBox Text="{Binding Path=TextBoxText}"/>
        </DockPanel>
    </Grid>
</UserControl>

usercontrol code behind

public partial class UserControlTextBox : UserControl
{
    public static DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(String), typeof(UserControl));
    public static DependencyProperty TextBoxTextProperty = DependencyProperty.Register("TextBoxText", typeof(String), typeof(UserControl));


    public String LabelText
    {
        get { return (String)GetValue(LabelTextProperty); }
        set { SetValue(LabelTextProperty, value); }
    }

    public String TextBoxText
    {
        get { return (String)GetValue(TextBoxTextProperty); }
        set { SetValue(TextBoxTextProperty, value); }
    }

    public UserControlTextBox()
    {
        InitializeComponent();
        GridLayout.DataContext = this;
    }
    }

example of call of the usercontrol in the main grid

<views:UserControlTextBox LabelText="Report Name:" TextBoxText="{Binding Path=CurrentReport.ReportName}" Grid.Row="1" Grid.ColumnSpan="2"/>

            <TextBlock Text="Header:" Grid.Row="2"/>
            <CheckBox Grid.Column="1" Grid.Row="2" IsChecked="{Binding Path=CurrentReport.Header}" 
                      VerticalContentAlignment="Stretch" VerticalAlignment="Center" Name="HeaderCheckBox"/>

            <Grid Grid.Row="3" Grid.ColumnSpan="2" Visibility="{Binding IsChecked, ElementName=HeaderCheckBox, Converter={StaticResource BoolToVisConverter}}">

                <views:UserControlTextBox LabelText="# Row Header:" TextBoxText="{Binding Path=CurrentReport.HeaderRow}"/>
            </Grid>

As you can see, CurrentReport.ReportName is a string but CurrentReport.HeaderRow is a int.

Is there any way to make the dependency property generic or based on a parameter passed to the usercontrol. Or is there any way of having validation to kick in before the user clicks the save button?

Thank you

Upvotes: 1

Views: 407

Answers (2)

blindmeis
blindmeis

Reputation: 22445

i wrote this a lot of time here on SO. the easiest way for this situations is to have a string Property in your viewmodel for binding to your view. then you just have to validate this property in your IDataErrorInfo to be a int. if this success you simple can convert your string to int before your save command is called.

as long as you have an int property in your viewmodel you can recieve BindingException all the time the input in not convertable to int.

ps: one way to ensure this is to use a numeric textbox or a masked behavior where just numbers allowed.

Upvotes: 0

GazTheDestroyer
GazTheDestroyer

Reputation: 21251

I would write a simple IntToStringConverter and then use that in your TextBoxText binding to pass in a string to your usercontrol.

Upvotes: 1

Related Questions