CoerceValueCallback does't works as expected
Hello everyone!
I have ItemsControl with ScrollViewer and it filled with items and some ot items can show error message. Need to scroll to such item if it has error message every time when user click button Save. I wrote such extension:
And use it in XAML like:
In ViewModel property looks like:
And it works fine in WPF blend project, but not in Unity(brings into view only first time, then if error stays true it doesn't scroll). Because if set same value in Error, in wpf CoerceValueCallback will be called but in Noesis won't. I can reset Error to null before checking for errors, it will help, but i'm looking for a more clean way.
I have ItemsControl with ScrollViewer and it filled with items and some ot items can show error message. Need to scroll to such item if it has error message every time when user click button Save. I wrote such extension:
Code: Select all
public class ScrollToElementExtension
{
public static readonly DependencyProperty ScrollToElementProperty = DependencyProperty.RegisterAttached(
"ScrollToElement",
typeof(bool),
typeof(ScrollToElementExtension),
new FrameworkPropertyMetadata(false, OnScrollToElementPropertyChanged, OnCoerceValue));
public static bool GetScrollToElement(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollToElementProperty);
}
public static void SetScrollToElement(DependencyObject obj, bool value)
{
obj.SetValue(ScrollToElementProperty, value);
}
private static object OnCoerceValue(DependencyObject d, object basevalue)
{
if ((bool)basevalue)
{
ScrollTo((FrameworkElement)d);
return true;
}
return false;
}
private static void OnScrollToElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
private static void ScrollTo(FrameworkElement element)
{
element.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => element.BringIntoView()));
}
}
Code: Select all
<DataTemplate DataType="{x:Type vm:AttachedMediaWithCaptureContainerVisual}">
<Grid x:Name="rootGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
x:Name="errMediaText"
Margin="0,0,0,8"
Foreground="{DynamicResource Brush.Alarm}"
Text="{loc:TranslateBinding KeyBinding={Binding Error}}"
TextWrapping="Wrap"
Visibility="Collapsed" />
...
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Error, Converter={StaticResource strNotEmpty}}" Value="True">
<Setter TargetName="errMediaText" Property="Visibility" Value="Visible" />
<Setter TargetName="rootGrid" Property="attach:ScrollToElementExtension.ScrollToElement" Value="True" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Code: Select all
...
public string? Error
{
get => error;
set
{
error = value;
RaisePropertyChanged(nameof(Error));
}
}
...
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: CoerceValueCallback does't works as expected
I've been analyzing what is happening in Noesis and the problem is that DataTrigger setters are not re-applied if the bound value does not really change.
And I see that in WPF, even if the binding value does not change, they re-apply the setters (although setter values should be already active). However, the EnterActions are not executed.
This behavior seems a bit strange to me, but we will investigate more because it is a deviation from WPF. Could you please report it in our bugtracker?
In the meantime, as you mentioned, you can reset the Error property before setting the new value.
And I see that in WPF, even if the binding value does not change, they re-apply the setters (although setter values should be already active). However, the EnterActions are not executed.
This behavior seems a bit strange to me, but we will investigate more because it is a deviation from WPF. Could you please report it in our bugtracker?
In the meantime, as you mentioned, you can reset the Error property before setting the new value.
Who is online
Users browsing this forum: No registered users and 5 guests