![](/img/trans.png)
[英]Data binding failing when trying to bind from MainWindow code-behind to UserControl code-behind
[英]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.