附加 属性 未更新它绑定到的值 (MVVM)

Attached property is not updating the value it is bind to (MVVM)

我有一个用绿色矩形填充的 ScrollViewer,我需要在每次更改时在 TextBlock 上报告它的滚动值(或百分比)。我还需要能够通过更改绑定到的 属性 来更改滚动值。

我已经创建了一个 Attached 属性 ScrollViewerBehavior 它给了我我需要的值,但是我将它绑定到我的视图模型 (ScrollValue) 的 属性该值未更新,因为从未达到 setter。视图模型与视图正确链接。

这是我的代码:
查看

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="6*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ScrollViewer Grid.Row="0" Background="Gray" local:ScrollViewerBehavior.ScrollState="{Binding ScrollValue, Mode=TwoWay}" >
        <StackPanel>
            <Rectangle Width="50" Height="50" Fill="Green" Margin="5" />
            <Rectangle Width="50" Height="50" Fill="Green" Margin="5" />
            <Rectangle Width="50" Height="50" Fill="Green" Margin="5" />
            <Rectangle Width="50" Height="50" Fill="Green" Margin="5" />
            <Rectangle Width="50" Height="50" Fill="Green" Margin="5" />
        </StackPanel>
    </ScrollViewer>

    <TextBlock Grid.Row="1" Text="{Binding ScrollValue}" />
</Grid>


ViewModel

public class MainViewModel : BaseViewModel
{
    private double _scrollValue = 0;
    public double ScrollValue
    {
        get { return _scrollValue; }
        set
        {
            // This code is never reached 
            _scrollValue = value;
            OnPropertyChanged("ScrollValue");
        }
    }
}


ScrollViewerBehavior

    public static double GetScrollState(DependencyObject obj)
    {
        return (double)obj.GetValue(ScrollStateProperty);
    }

    public static void SetScrollState(DependencyObject obj, double value)
    {
        obj.SetValue(ScrollStateProperty, value);
    }

    public static readonly DependencyProperty ScrollStateProperty =
        DependencyProperty.RegisterAttached("ScrollState", typeof(double), typeof(ScrollViewerBehavior), new PropertyMetadata(0.5, (o, e) =>
        {
            var scrollViewer = o as ScrollViewer;
            
            if (scrollViewer == null)
            {
                return;
            }
            else
            {
                double newVO = (double)e.NewValue * scrollViewer.ScrollableHeight;
                scrollViewer.ScrollToVerticalOffset(newVO);
                SetScrollState(o, newVO);
            }
        }));

我看不到我错过了什么

我在代码中没有看到您更改 ScrollValue 值的任何地方。由于您附加的 属性 绑定到此,因此它仅在您的视图模型中的 ScrollValue 更新时更新。除非我误解了您的解释,否则您希望在每次滚动条值更改时更新 ScrollValue。为此,您可以连接到 ScrollChanged 事件:

(我只更新了你的代码,只是显示了需要的内容)

public static readonly DependencyProperty ScrollStateProperty =
    DependencyProperty.RegisterAttached("ScrollState", typeof(double), typeof(ScrollViewerBehavior), new PropertyMetadata(0.5, (o, e) =>
        {
            if (o is ScrollViewer scrollViewer)
            {
                scrollViewer.ScrollChanged += OnScrollChanged;
            }
        }));

    private static void OnScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        if (sender is ScrollViewer scrollViewer)
        {
            SetScrollState(scrollViewer, scrollViewer.VerticalOffset);
        }
    }