简体   繁体   中英

Dependency property of user control doesn't bind to a property of ViewModel

I have an implementation of IntegerUpDown:

<UserControl x:Class="Scoreboard.View.IntegerUpDown"
         ...
         xmlns:local="clr-namespace:Scoreboard.View"
         d:DesignHeight="28" Width="86"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <StackPanel Orientation="Horizontal">
        <TextBox x:Name="TxtNum" x:FieldModifier="private" Margin="0,5,0,5" Width="50" 
                 Text="{Binding NumValue,Converter={local:NumberToStringConverter}, Mode=TwoWay}" PreviewTextInput="TxtNum_PreviewTextInput"/>

        <!-- Nothing interesting below -->
        <Button Margin="0,5" x:Name="CmdUp" x:FieldModifier="private" Width="18" Click="cmdUp_Click" >
            <Path Data="M 0,300 L 0,300 200,0 400,300" Stretch="Fill" Width="8.333" Height="5.833" Stroke="Black"/>
        </Button>
        <Button Margin="0,5" x:Name="CmdDown" x:FieldModifier="private" Width="18" Click="cmdDown_Click" >
            <Path Data="M 0,-300 L 0,-300 -200,0 -400,-300" Stretch="Fill" Width="8.333" Height="5.833" Stroke="Black"/>
        </Button>
    </StackPanel>
</Grid>

and code behind:

public partial class IntegerUpDown
{
    public int MaxValue { get; set; } = int.MaxValue;

    public int NumValue
    {
        get { return (int)GetValue(NumValueProperty); }
        set { SetValue(NumValueProperty, value); }
    }

    public static readonly DependencyProperty NumValueProperty =
        DependencyProperty.Register("NumValue",
        typeof(int), typeof(IntegerUpDown), new PropertyMetadata(0));


    public IntegerUpDown()
    {
        InitializeComponent();
    }

    //Nothing interesting below
    private void cmdUp_Click(object sender, RoutedEventArgs e)
    {
        if (NumValue < MaxValue)
        {
            NumValue++;
        }
    }

    private void cmdDown_Click(object sender, RoutedEventArgs e)
    {
        if (NumValue > 0)
        {
            NumValue--;
        }
    }
}

IntegerUpDown works fine as a standalone. Text in its TextBox is same as DP NumValue. The problem is when this control is used by another one and I want to bind NumValue with a different property. Like this

<UserControl x:Class="Scoreboard.View.TeamGameControl"
             ...
             d:DataContext="{d:DesignInstance ViewModel:ControlPanel}">
             <local:IntegerUpDown ... NumValue="{Binding Val, Mode=TwoWay}"/>
             <!--               doesn't do anything ↑ ... why? -->

And how looks property Val in DataContext:

public class ControlPanel : INotifyPropertyChanged {
    public int Val
        {
            get { return _val; }
            set
            {
                _val = value;
                RaisePropertyChangedEvent("Val");
            }
        }
    }

None of the two properties (Val, NumValue) is ever updated. What am I doing wrong?

EDIT: I have cut out the necessary parts and here is the project .

Please use relativesource with ancestor level 2

NumValue={Binding Value,Mode =TwoWay, 
          RelativeSource={RealtiveSource AncestorType =UserControl, AncestorLevel= 2}

Else you can use ElementName instead of RelativeSource

Let me know if this helps.

Note:I am typing from IPhone..Please check the Syntax

Thanks to slugster I managed to repair it. In the IntegerUpDown I had to remove the DataContext. And then bind the Text of the TextBox like this

Text="{Binding NumValue,Converter={local:NumberToStringConverter}, Mode=TwoWay,
       RelativeSource={RelativeSource AncestorType={x:Type local:IntegerUpDown}}}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM