如何在资源字典中绑定数据模板中的命令?



我正在尝试制作更好的解决方案架构,为此我将代码的许多部分分离在不同的文件中。因为我的应用程序使用大量数据模板,所以我将它们推送到不同的 ResourceDictionary.xaml 文件中。

问题:

我有一个视图Agenda.xaml,视图模型AgendaViewModel。此视图具有一个列表视图,该视图在外部资源字典文件中调用其数据模板。但是,如果我想在 dataTemplate 中放置一个绑定命令,则该命令永远不会执行,因为(我猜(资源字典在哪里我的数据模板没有引用 ViewModel。

我能做什么?

我已经尝试了一些奇怪的绑定代码,例如

<TapGestureRecognizer Command="{Binding BindingContext.OpenActiviteCommand, Source={x:Reference agendaPage}}" CommandParameter="{Binding .}"/>

其中"agendaPage"是 x:Agenda.xaml 的名称。

我在谷歌上找到的只是关于 WPF 和绑定属性,在 Xamarin 窗体上不可用(RelativeSource、ElementName 等...(

我知道我可以把dataTemplate放在我的Agenda.xaml视图中,但我真的想把它保存在一个外部文件中。我想避免查看 1500 行的文件....

这是我的议程.xaml 视图

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Corim.Portable.CorimTouch.ViewForms.Agenda.AgendaViewDetail"
             xmlns:converters="clr-namespace:Corim.Portable.CorimTouch.Converters"
             Title="Agenda"
             x:Name="agendaPage">
    <ContentPage.Content>
        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"  BackgroundColor="{StaticResource LightGrayCorim}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <!-- Liste itv,pointage,activite -->
            <ListView 
                x:Name="listAgenda"
                Grid.Row="1"
                SeparatorVisibility="None"
                HasUnevenRows="True"
                SelectionMode="None"
                CachingStrategy="RecycleElement"
                ItemsSource="{Binding AgendaList}"
                ItemTemplate="{StaticResource agendaTemplateSelector}"
                BackgroundColor="{StaticResource LightGrayCorim}">
            </ListView>
        </Grid>
    </ContentPage.Content>
</ContentPage>

这是 AgendaTemplates.xaml 中 Datatemplate 的一部分

<DataTemplate x:Key="agenda-adresse-intervention">
        <ViewCell>
            <Frame Margin="10,5,10,0" HasShadow="False" Padding="0" CornerRadius="10" IsClippedToBounds="True">
                <controls:CustomTappedStackLayout
                    BackgroundColor="White"
                    TappedBackgroundColor="{StaticResource RollOver}"
                    HorizontalOptions="FillAndExpand"
                    Orientation="Horizontal"
                    Padding="10">
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding Path=BindingContext.OpenParcCommand, Source={x:Reference agendaPage}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1"/>
                    </StackLayout.GestureRecognizers>
                    <Image
                        Source="localisation_adresse"
                        WidthRequest="30"
                        HeightRequest="30"
                        Aspect="AspectFit"
                        HorizontalOptions="Start"
                        Margin="10"
                        VerticalOptions="StartAndExpand"/>
                    <StackLayout
                        HorizontalOptions="FillAndExpand"
                        Orientation="Vertical">
                        <Label
                        Text="{Binding Client}"
                        IsVisible="{Binding Client, Converter={StaticResource StringEmptyBooleanConverter}}"
                        FontFamily="{StaticResource SemiBoldFont}"
                        FontSize="{StaticResource MediumTextSize}"
                        TextColor="Black"/>
                        <Label
                        Text="{Binding Title}"
                        IsVisible="{Binding Title, Converter={StaticResource StringEmptyBooleanConverter}}"
                        FontFamily="{StaticResource RegularFont}"
                        FontSize="{StaticResource DefaultTextSize}"
                        TextColor="Gray"/>
                    </StackLayout>
                </controls:CustomTappedStackLayout>
            </Frame>
        </ViewCell>
    </DataTemplate>

但是如果我想在dataTemplate中放置一个绑定命令,命令 永远不会执行,因为(我猜(资源字典在哪里 我的数据模板未引用视图模型。

你猜错了:做你正在做的事情是完全可以的,应该透明地工作。绑定在运行时解析,您的数据模板不知道将绑定的对象的任何信息。

第一:放弃BindingContext.OpenActiviteCommand废话:)只需绑定到OpenActiviteCommand,唯一的问题是:

第二:你的OpenActiviteCommand在哪里?

AgendaTemplates的数据上下文是AgendaList中的项目。 如果AgendaList的类型是ObservableCollection<AgendaViewModel>,并且您的AgendaViewModelOpenParcCommand那么应该没问题:

public class AgendaViewModel
{
    public AgendaViewModel(ICommand openParcCommand)
    {
        OpenParcCommand = openParcCommand;
    }
    public ICommand OpenParcCommand { get; }
}

在你的AgendaPageViewModel

public class AgendaPageViewModel
{
    public ObservableCollection<AgendaViewModel> AgendaList { get; }
}

感谢@Roubachof

解决方案被AgendaDataViewModel的ListView取代了我的干预模型列表视图。

AgendaViewModel是一个新类,它包含我需要的所有命令和一个干预模型。

这是议程数据视图模型:

public class AgendaDataViewModel : HybridContentViewModel
    {
        private InterventionModel _model;
        public InterventionModel Model
        {
            get => _model;
            set { _model = value; }
        }
        public ICommand OpenActiviteCommand { get; private set; }
        public AgendaDataViewModel()
        {
            this.OpenActiviteCommand = new Command<InterventionModel>(this.OpenActivite);
        }
        /// <summary>
        /// Ouvre le formulaire d'édition de l'activité
        /// </summary>
        /// <param name="model"></param>
        private void OpenActivite(InterventionModel model)
        {
            //TODO amener sur le formulaire d'activité
        }
    }

我的议程模板.xaml


 <!--Template pour l'affichage du parc-->
    <DataTemplate x:Key="agenda-adresse-intervention">
        <ViewCell>
            <Frame Margin="10,5,10,0" HasShadow="False" Padding="0" CornerRadius="10" IsClippedToBounds="True">
                <controls:CustomTappedStackLayout
                    BackgroundColor="White"
                    TappedBackgroundColor="{StaticResource RollOver}"
                    HorizontalOptions="FillAndExpand"
                    Orientation="Horizontal"
                    Padding="10">
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding OpenParcCommand}" CommandParameter="{Binding Model}" NumberOfTapsRequired="1"/>
                    </StackLayout.GestureRecognizers>
                    <Image
                        Source="localisation_adresse"
                        WidthRequest="30"
                        HeightRequest="30"
                        Aspect="AspectFit"
                        HorizontalOptions="Start"
                        Margin="10"
                        VerticalOptions="StartAndExpand"/>
                    <StackLayout
                        HorizontalOptions="FillAndExpand"
                        Orientation="Vertical">
                        <Label
                        Text="{Binding Model.Client}"
                        IsVisible="{Binding Model.Client, Converter={StaticResource StringEmptyBooleanConverter}}"
                        FontFamily="{StaticResource SemiBoldFont}"
                        FontSize="{StaticResource MediumTextSize}"
                        TextColor="Black"/>
                        <Label
                        Text="{Binding Model.Title}"
                        IsVisible="{Binding Model.Title, Converter={StaticResource StringEmptyBooleanConverter}}"
                        FontFamily="{StaticResource RegularFont}"
                        FontSize="{StaticResource DefaultTextSize}"
                        TextColor="Gray"/>
                    </StackLayout>
                </controls:CustomTappedStackLayout>
            </Frame>
        </ViewCell>
    </DataTemplate>

如您所见,值绑定由以下行进行:

{Binding Model.Client}

其中客户端是绑定属性的名称。要绑定命令,您不需要 Model,只需像这样绑定:

Command={Binding CommandName}

希望将来对某人有所帮助!

相关内容

  • 没有找到相关文章

最新更新