Help: Binding to property of a UserControl

Topics: Conventions, Getting Started, UI Architecture
Aug 16, 2012 at 8:35 PM

Hi, I'm new to this framework and trying to figure out all of its idiosyncrasies. I have a simple user control TextBoxWithLabel that is a composition of a Label and TextBox in a DockPanel. I have the x:Name property set to the name of the property in the view model to which it's supposed to bind, but it doesn't bind to the 'Text' property; it tries to bind to the 'Visibility' property as is evidenced by the Output window. This happens even if I explicitly specify the binding in the markup. I don't understand why it's trying to bind to 'Visibility'. I'm sure it has to do either with my implementation of the user control, or something extra I need to do to describe to the framework how to bind to the control, but I don't know where to start.

User control definition:

    <Grid>
        <DockPanel
            LastChildFill="True">
            <Label
                DockPanel.Dock="Left"
                HorizontalContentAlignment="Right"
                VerticalContentAlignment="Center"
                Content="{Binding Path=LabelContent, 
                             RelativeSource={RelativeSource FindAncestor, 
                                             AncestorType=my:TextBoxWithLabel, 
                                             AncestorLevel=1}}"
                Width="{Binding RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType=my:TextBoxWithLabel, 
                                    AncestorLevel=1}, 
                                    Path=LabelWidth}" />
            <TextBox
                HorizontalContentAlignment="Left"
                VerticalContentAlignment="Center"
                Width="{Binding RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType=my:TextBoxWithLabel, 
                                    AncestorLevel=1}, 
                                    Path=TextBoxWidth}"
                Text="{Binding RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType=my:TextBoxWithLabel, 
                                    AncestorLevel=1}, 
                                    Path=Text}"
                IsReadOnly="{Binding RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType=my:TextBoxWithLabel, 
                                    AncestorLevel=1}, 
                                    Path=IsReadOnly}"></TextBox>
        </DockPanel>
    </Grid>

Use in XAML:

        <my:TextBoxWithLabel
            x:Name="ReportStatus"
            LabelContent="Report Status:"
            IsReadOnly="True" />
        <my:TextBoxWithLabel
            x:Name="WellStatus"
            Text="{Binding WellStatus, Mode=TwoWay}"
            IsReadOnly="True"
            LabelContent="Well Status:" />

Errors from output:

System.Windows.Data Error: 1 : Cannot create default converter to perform 'two-way' conversions between types 'System.Int16' and 'System.Windows.Visibility'. Consider using Converter property of Binding. BindingExpression:Path=WellStatus; DataItem='RigInfoViewModel' (HashCode=58388009); target element is 'TextBoxWithLabel' (Name='WellStatus'); target property is 'Visibility' (type 'Visibility')

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='1' BindingExpression:Path=WellStatus; DataItem='RigInfoViewModel' (HashCode=58388009); target element is 'TextBoxWithLabel' (Name='WellStatus'); target property is 'Visibility' (type 'Visibility')