簡體   English   中英

ViewModel 在嘗試從代碼隱藏訪問時總是返回 null

[英]ViewModel always returns null when trying to access it from code-behind

我還在學習Xamarin.Forms,所以請多多包涵。

我正在開發一個控件,讓您用相機拍照,將它們顯示在 FlowListView 中,然后最終我想拍攝這些照片,將它們轉換為電子郵件附件並發送出去。

雖然控件的 Gallery 部分正在工作並且 E-Mail 部分已經由其他人編寫,但由於某種原因,我無法從 E-Mail Code-Behind 訪問控件的 ViewModel。

我在 MVVM 中編寫了控件,電子郵件部分是在 xaml 中編寫的,帶有代碼隱藏。

每當我嘗試訪問 ImagePickerViewModel 以獲取 AttachmentList 的內容時,都會返回 null。

我已經嘗試不在電子郵件代碼隱藏中初始化 ImagePickerViewModel,它仍然返回 null。

這樣做的正確方法是什么?

ImagePickerViewModel.cs

 [XamlCompilation(XamlCompilationOptions.Compile)]
    public class ImagePickerViewModel : BindableObject, INotifyPropertyChanged
    {
        // HERE WOULD BE A TON OF DEPENDENCIES

        public ImagePickerViewModel()

        {
            // Commands
            TakePictureCmd = new Command(TakePicture);

            //ObservableCollection
            TakenPicturesList = new ObservableCollection<Model.ImagePicker>();
            AttachmentList = new List<BaseObject>();   
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public Model.ImagePicker NewPicture { get; set; }

        public BaseObject attachment { get; set; }
        public List<BaseObject> AttachmentList { get; set; }

        public ObservableCollection<Model.ImagePicker> TakenPicturesList { get; set; }

        public string selectedImage { get; set; }
        public string Path
        {
            get { return NewPicture.ImagePath; }
            set { NewPicture.ImagePath = value; OnPropertyChanged(nameof(Path)); }
        }

        public Command TakePictureCmd { get; set; }


        private async void TakePicture()
        {
            var path = await _cameraService.TakePictureAsync();
            TakenPicturesList.Add(new Model.ImagePicker { ImagePath = path });
            GetFilesForAttachment(path);
        }


        private void GetFilesForAttachement(string filePath)
        {
            attachment = Attachment.FromFile(filePath);
            if (attachment != null)
            {
                AttachmentList.Add(attachment);
            }
        }

        public void RaisedOnPropertyChanged(string _PropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_PropertyName));
        }
    }

ImagePickerView.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
             xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
             xmlns:local="clr-namespace:SolIT.Mobile.Client" 
             xmlns:vm="clr-namespace:SolIT.Mobile.Client.Features.Shared.Controls.ImagePicker.ViewModel"
             xmlns:buttons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
             x:Class="SolIT.Mobile.Client.Features.Shared.Controls.ImagePicker.View.ImagePickerView"
             x:Name="View_ImagePickerView">
    <ContentView.BindingContext>
        <vm:ImagePickerViewModel ContextView="{x:Reference View_ImagePickerView}"/>
    </ContentView.BindingContext>

    <Frame>
        <ContentView.Content>
            <StackLayout>

                <Grid 
          ColumnSpacing="0"
          HorizontalOptions="CenterAndExpand">

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <buttons:SfButton
            x:Name="Btn_takePicture"
            Grid.Column="1"
            Text="{local:Translate Common.SelectFilesPage.TakePicture}"
            TextColor="Black"
            ImageSource="{Binding TakePictureIcon}"
            ShowIcon="true"
            BackgroundColor="Transparent"
            ImageAlignment="Top"
            HorizontalOptions="FillAndExpand"
            Margin="3"
            CornerRadius="5"
            Command="{Binding TakePictureCmd}"/>
                </Grid>

                <BoxView Grid.ColumnSpan="2" Grid.Row="1" HeightRequest="1" BackgroundColor="{StaticResource Win10Devider}"/>

                <flv:FlowListView x:Name="pictureFlowListView" SeparatorVisibility="None" HasUnevenRows="true"
            FlowColumnMinWidth="110" FlowItemsSource="{Binding TakenPicturesList}">
                                  <!--FlowItemTappedCommand="{Binding PictureTappedCmd}"
                                  FlowLastTappedItem="{Binding SelectedItem}"-->
                    <flv:FlowListView.FlowColumnTemplate>
                        <DataTemplate> 
                            <Grid Padding="3">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <StackLayout>
                                <ffimageloading:CachedImage HeightRequest="100" Aspect="AspectFill"
                            DownsampleHeight="100" DownsampleUseDipUnits="false" x:Name="imageCached"
                            Source="{Binding ImagePath}">
                                    <ffimageloading:CachedImage.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding Path=BindingContext.PictureTappedCmd, Source={x:Reference pictureFlowListView}}" CommandParameter="{x:Reference imageCached}"></TapGestureRecognizer>
                                    </ffimageloading:CachedImage.GestureRecognizers>
                                </ffimageloading:CachedImage>
                                </StackLayout>
                            </Grid>
                        </DataTemplate>
                    </flv:FlowListView.FlowColumnTemplate>
                </flv:FlowListView>
            </StackLayout>
        </ContentView.Content>
    </Frame>
</ContentView>

EmailCreatePage.xaml.cs

 [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class EmailCreatePage: ContentPage
    {
        // HERE WOULD BE A TON OF DEPENDENCIES

        public EmailCreateViewModel ViewModel { get; }
        public ImagePickerViewModel ViewModelImagePicker {get;}

        public EmailCreatePage()
        {
            InitializeComponent();
            BindingContext = ViewModel = new EmailCreateViewModel();
            ViewModelImagePicker = new ImagePickerViewModel();
        }
private void CreateAttachment()
        {
 
                var attachmentList = GetFileList();
                foreach (var file in attachmentList)
                {
                    var attachment = Attachment.FromFile(file.ToString());
                    if (attachment != null)
                    {

                        ViewModel.CubesMessage.ConnectedObjects.Add(attachment);
                    }
            }

public List<BaseObject> GetFileList()
        {
// GET LIST FROM OTHER VIEWMODEL HERE
// VIEWMODEL IS ALWAYS NULL
          var attachmentList = ImagePickerViewModel.AttachmentList;
          return attachmentList;
}

// HERE WOULD BE THE CODE THAT SENDS THE EMAIL OFF AFTER A BUTTON CLICK

從您發布的以下代碼中,我們發現您希望從ImagePickerViewModel訪問變量AttachmentList 但在這里,您只需創建一個 class ImagePickerViewModel的新實例,因此attachmentList列表將始終為 null。

   ViewModelImagePicker = new ImagePickerViewModel();

此外,您還使用代碼ImagePickerViewModel.AttachmentList; 訪問ImagePickerViewModel中的變量AttachmentList ,這很令人困惑。 在這里,您可以刪除代碼ViewModelImagePicker = new ImagePickerViewModel(); .

public List<BaseObject> GetFileList()
        {
// GET LIST FROM OTHER VIEWMODEL HERE
// VIEWMODEL IS ALWAYS NULL
          var attachmentList = ImagePickerViewModel.AttachmentList;
          return attachmentList;
}

實際上,如果要從其他頁面獲取 class ImagePickerViewModel中的變量AttachmentList的值,可以定義一個全局的static變量AttachmentList

如下:

   public stactic List<BaseObject> AttachmentList { get; set; }

注意:確保 class ImagePickerViewModel中的AttachmentList可以正確分配值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM