附加 属性 未更新它绑定到的值 (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);
}
}
我有一个用绿色矩形填充的 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);
}
}