2

I am having trouble getting any binding to work for a SwipeItem within a RadListView (which is similar to a standard ListView). In particular, I am trying to bind to the Command property; however, I have attempted to bind to other properties, e.g., Text, but to no avail.

<telerikDataControls:RadListView ItemsSource ="{Binding Users, Mode=OneWay}">
    <telerikDataControls:RadListView.ItemTemplate>
        <DataTemplate>
             <SwipeControl>
                    <SwipeControl.RightItems>
                        <SwipeItems>
                            <SwipeItem Text="Delete"
                                       Background="Red"
                                       Foreground="White"
                                       Command="{Binding DeleteCommand}">
                                <SwipeItem.IconSource>
                                    <SymbolIconSource Symbol="Delete"/>
                                </SwipeItem.IconSource>
                            </SwipeItem>
                        </SwipeItems>
                    </SwipeControl.RightItems>
                    <Grid>
                        <TextBlock Text="{Binding Name"/>
                    </Grid>
             </SwipeControl>
        </DataTemplate>
    </telerikDataControls:RadListView.ItemTemplate>
</telerikDataControls:RadListView>

Users is set in the constructor of the ViewModel for the View; it is an ObservableCollection of UserViewModel, each of which has the properties I am trying to use (with PropertyChanged events).

The Name binding works in the Grid further down in the template and I have checked the DataContext of the SwipeControl and it is a UserViewModel. In my testing I have set up an Event on the SwipeItem:

 <SwipeItem Text="Delete"
            Background="Red"
            Foreground="White"
            Command="{Binding DeleteCommand}"
            Invoked="SwipeItem_Invoked">

and handled it in the code-behind:

private void SwipeItem_Invoked(SwipeItem sender, SwipeItemInvokedEventArgs args)
{
    UserViewModel userToDelete = (UserViewModel)args.SwipeControl.DataContext;
}

I can see in here that sender.Command is null.

Obviously, the quick solution is to use the Event pattern; however, I am trying to keep it MVVM and avoid code-behind as much as possible. I have never had issues binding to properties before so imagine I am just doing something fundamentally wrong.

Thanks.

Edit:

public class UserViewModel : MvxNotifyPropertyChanged // MvvmCross
{
    public IMvxAsyncCommand DeleteCommand { get; }

    private string _name;
    public string Name // this property is bound in the Grid but will not bind in the SwipeItem
    {
        get => _name;
        set => SetProperty(ref _name, value);
    } 
}
boreholer
  • 21
  • 3
  • Take a look at this question about command bindings. https://stackoverflow.com/questions/12422945/how-to-bind-wpf-button-to-a-command-in-viewmodelbase – Hirasawa Yui Nov 30 '18 at 16:53
  • Is the `DeleteCommand` in the `UserViewModel` class? Could you post the `UserViewModel` class code? – Martin Zikmund Dec 01 '18 at 06:42
  • @HirasawaYui thank you for the link; however, it is a beginner level link. I know how bindings work - I use them all the time. There seems to be an issue with the `SwipeItem` and binding to its properties, though. – boreholer Dec 04 '18 at 09:31
  • @MartinZikmund I have updated the question as per your request. Both the `Name` and `DeleteCommand` are in the `UserViewModel`. Neither will bind in the `SwipeItem`; however, they will bind outside of the `SwipeItem`, for example, in the `Grid` further down in the `DataTemplate`. I imagine there is some quirk with the `SwipeItem` that is overwriting the binding or even ignoring it - I have purposely made incorrect bindings for the `SwipeItem` and no warnings occur. – boreholer Dec 04 '18 at 09:40

2 Answers2

0

If the Invoked event is firing, but you're unable to get the Command binding to work, then you could try using XAML Behaviors (aka Blend Behaviors) to wire your command up to the event that is firing. This should then allow you to keep your code MVVM friendly.

First, install the Microsoft.Xaml.Behaviors.Uwp.Managed nuget package, then alter your XAML to the following:

<SwipeItem xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
           xmlns:core="using:Microsoft.Xaml.Interactions.Core"
           Text="Delete"
           Background="Red"
           Foreground="White">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="Invoked">
            <core:InvokeCommandAction Command="{Binding Path=DeleteCommand}" />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    <SwipeItem.IconSource>
        <SymbolIconSource Symbol="Delete"/>
    </SwipeItem.IconSource>
</SwipeItem>

To keep the answer concise, I've defined the interactivity and core xml namespaces within the SwipeItem element - but these would normally be moved to the top-level element in your XAML.

Stoph
  • 11
  • I found the idea creative, I tried it, and unfortunately it doesn't work. In the UWP Discord server it was explained here as follows: https://discord.com/channels/372137812037730304/580484470877061120/764217956611391489 – hansmbakker Oct 09 '20 at 20:45
0

As your Command is inside the DataTemplate its BindingContext is Item so defining the Command in the ViewModel won't work. There are various ways to resolve this, e.g. you could define Command in the item or to bind to the proper context.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57