Skip to content

[MVUX] Retry in FeedView.ErrorTemplate is a silently dead button: {Binding Refresh} resolves against the Exception #3141

Description

@mtmattei

Current behavior

Inside FeedView.ErrorTemplate, the DataContext is the thrown Exception, not the FeedViewState. So the natural way to wire a Retry button:

<mvux:FeedView Source="{Binding Products}">
  <mvux:FeedView.ErrorTemplate>
    <DataTemplate>
      <Button Content="Retry" Command="{Binding Refresh}" />
    </DataTemplate>
  </mvux:FeedView.ErrorTemplate>
</mvux:FeedView>

...binds Command to nothing. The button still renders enabled, still exposes an invoke pattern to automation, and does nothing at all when clicked. {Binding Parent.X} fails there for the same reason, since Parent also lives on FeedViewState.

The reason this is worth reporting rather than just documenting: every cheap verification passes. The build succeeds, there is no binding-failure symptom at the usual severity, the button looks correct in a screenshot, and the same {Binding Refresh} expression is valid inside ValueTemplate — so it survives code review by pattern-matching against working code. The only way to discover it is to click the button with a healthy data source and notice nothing happened.

I confirmed the cause at runtime by inspecting the button's DataContext in a running app: it serialises as System.InvalidOperationException (the exception the feed threw), with no Refresh member anywhere on it.

Expected behavior

Either:

  1. Refresh (and ideally FeedViewState) is reachable from ErrorTemplate's DataContext, so the obvious binding works; or
  2. the failed binding surfaces loudly — a binding error at a visible severity, or an analyser warning on {Binding Refresh} inside an ErrorTemplate; or
  3. at minimum, the docs for FeedView error handling show the ElementName form explicitly, since the obvious form is a silent no-op.

Workaround

Name the FeedView and bind through ElementName, which resolves correctly even from inside a nested ContentTemplate:

<mvux:FeedView x:Name="ProductsFeed" Source="{Binding Products}">
  <mvux:FeedView.ErrorTemplate>
    <DataTemplate>
      <Button Content="Retry" Command="{Binding Refresh, ElementName=ProductsFeed}" />
    </DataTemplate>
  </mvux:FeedView.ErrorTemplate>
</mvux:FeedView>

How to reproduce it

  1. Expose an IFeed<T> / IListFeed<T> whose service throws.
  2. Bind a FeedView to it with an ErrorTemplate containing <Button Command="{Binding Refresh}" />.
  3. Run, let it fail into the error state, then make the data source healthy while the app is still running and click Retry — the service is never called again.
  4. Swap in the ElementName form and repeat — the service is called and the feed recovers.

Environment

  • Uno.Sdk 6.7.0-dev.105 and 6.8.0-dev.12 (same behaviour on both)
  • net10.0-desktop
  • Windows 11, .NET 10.0.303

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions