因此,我正在尝试从服务器中下载字节中的图像,但图像不会显示。我得到了一个适当的字节阵列并重新汇总。它可以从imagegallerypagemodel中添加图片,但在issuePageModel中添加它们时不起作用。因此,我怀疑该班级是错误的,要么通知Property不起作用。我尝试仅添加相关零件,但可以添加任何缺少的部分。
收藏
public class ImageGalleryPageModel
{
public ObservableCollection<ImageModel> Images
{
get { return images; }
}
private ObservableCollection<ImageModel> images = new ObservableCollection<ImageModel>();
这可以添加此类的图片
private async Task ExecutePickCommand()
{
MediaFile file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
byte[] imageAsBytes;
using (MemoryStream memoryStream = new MemoryStream())
{
file.GetStream().CopyTo(memoryStream);
file.Dispose();
imageAsBytes = memoryStream.ToArray();
}
if (imageAsBytes.Length > 0)
{
IImageResizer resizer = DependencyService.Get<IImageResizer>();
imageAsBytes = resizer.ResizeImage(imageAsBytes, 1080, 1080);
ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
Images.Add(new ImageModel { Source = imageSource, OrgImage = imageAsBytes });
}
}
然后我第二次加载IssuePageModel,这是ImageGalleryPageModel
的实例public class IssuePageModel : FreshBasePageModel, INotifyPropertyChanged
{
public ImageGalleryPageModel ImageGalleryViewModel { get; set; } = new ImageGalleryPageModel();
然后,我下载图像并将其放入集合中,触发了NotifyProperty,我可以看到在调试它时,我可以在设定的部分上看到它。
private void AddTheImages(int imageIssueId)
{
var imageData = App.Client.GetImage(imageIssueId);
byte[] imageAsBytes = imageData.Item1;
if (imageAsBytes.Length > 0)
{
IImageResizer resizer = DependencyService.Get<IImageResizer>();
imageAsBytes = resizer.ResizeImage(imageAsBytes, 1080, 1080);
ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
ImageGalleryViewModel.Images.Add(new ImageModel { Source = imageSource, OrgImage = imageAsBytes });
}
}
整个XAML
<freshMvvm:FreshBaseContentPage NavigationPage.HasNavigationBar="false" xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:freshMvvm="clr-namespace:FreshMvvm;assembly=FreshMvvm"
xmlns:converters="clr-namespace:ASFT.Converters;assembly=ASFT"
xmlns:maps="clr-namespace:ASFT.PageModels;assembly=ASFT"
xmlns:controls="clr-namespace:ASFT.Controls;assembly=ASFT"
x:Class="ASFT.Pages.IssuePage" Padding="4,25,4,4" x:Name="IssuePages">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="Labelfont" TargetType="Label">
<Setter Property="FontSize" Value="Medium" />
</Style>
<converters:DateTextConverter x:Key="DateToTextConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid BackgroundColor="Black">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<!--Top Navigation Bar RETURN TO EVENTS-->
<Grid Grid.Row="0" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" BackgroundColor="#FBB040">
<Label Text=" < EVENTS" TextColor="White" FontSize="Large" HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnGoToListCommand}" NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding LocationText}" TextColor="Black"/>
</StackLayout>
</Grid>
<ScrollView Grid.Column="0" Grid.Row="1" Orientation="Vertical" VerticalOptions="FillAndExpand">
<StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Spacing="15" Padding="0,30,0,0">
<!--Category-->
<Label Text="CATEGORY" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"
Style="{StaticResource Labelfont}" TextColor="White" />
<Frame OutlineColor="#FBB040" Padding="2" HeightRequest="40">
<StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand"
Spacing="6" HeightRequest="40">
<Entry Text="{Binding TitleEx}" TextColor="White" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" Style="{StaticResource Labelfont}" HeightRequest="40"
BackgroundColor="Black" />
</StackLayout>
</Frame>
<!--Title-->
<Label Text="TITLE" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"
Style="{StaticResource Labelfont}" TextColor="White" />
<Frame OutlineColor="#FBB040" Padding="2" HeightRequest="40">
<StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand"
Spacing="6" HeightRequest="40">
<Entry Text="{Binding TitleEx}" TextColor="White" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" Style="{StaticResource Labelfont}" HeightRequest="40"
BackgroundColor="Black" />
</StackLayout>
</Frame>
<!--PictureGallery-->
<Label Text="IMAGES" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"
Style="{StaticResource Labelfont}" TextColor="White" />
<Grid BindingContext="{Binding ImageGalleryViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height="128" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:ImageGalleryControl Grid.Row="0" ItemsSource="{Binding Images}">
<controls:ImageGalleryControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Source}" Aspect="AspectFit">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Path=BindingContext.PreviewImageCommand, Source={x:Reference IssuePages}}"
CommandParameter="{Binding ImageId}" />
</Image.GestureRecognizers>
</Image>
</DataTemplate>
</controls:ImageGalleryControl.ItemTemplate>
</controls:ImageGalleryControl>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Text="Add photo" Command="{Binding CameraCommand}" />
<Button Grid.Column="1" Text="Pick photo" Command="{Binding PickCommand}" />
</Grid>
</Grid>
<Label Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3" Text="{Binding ImageText}" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White" />
<!--Description-->
<Label Text="DESCRIPTION" HorizontalTextAlignment="Start" VerticalTextAlignment="Center" Style="{StaticResource Labelfont}" TextColor="White" />
<Frame Padding="2" OutlineColor="#FBB040">
<Editor Text="{Binding DescriptionEx}" HeightRequest="100" BackgroundColor="Black" TextColor="White" />
</Frame>
<!--Grid for Status and Severity-->
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--Severity-->
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Text="SEVERITY" HorizontalTextAlignment="Start" VerticalTextAlignment="Center" Style="{StaticResource Labelfont}" TextColor="White" />
<Label Grid.Row="0" Grid.Column="1" Text="" VerticalTextAlignment="Center"
HorizontalOptions="StartAndExpand" Style="{StaticResource Labelfont}" />
<StackLayout Grid.Row="1" Grid.Column="0" Orientation="Horizontal" HorizontalOptions="Center">
<Image Source="severity_5.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="{Binding Severity5Opacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="severity_5.png" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="1">
<Image Source="severity_4.png" HorizontalOptions="Center"
VerticalOptions="Center" HeightRequest="40" Opacity="{Binding Severity4Opacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="severity_4.png" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="2">
<Image Source="severity_3.png" HorizontalOptions="Center"
VerticalOptions="Center" HeightRequest="40" Opacity="{Binding Severity3Opacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="severity_3.png" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="3">
<Image Source="severity_2.png" HorizontalOptions="Center"
VerticalOptions="Center" HeightRequest="40" Opacity="{Binding Severity2Opacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="severity_2.png" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="4">
<Image Source="severity_1.png" HorizontalOptions="Center"
VerticalOptions="Center" HeightRequest="40" Opacity="{Binding Severity1Opacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="severity_1.png" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<!--Status-->
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Text="STATUS" HorizontalTextAlignment="Start" VerticalTextAlignment="Center" TextColor="White" Style="{StaticResource Labelfont}" />
<Label Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" FontSize="Micro" Text="STATUS" HorizontalTextAlignment="End" VerticalTextAlignment="Center" TextColor="White"
Style="{StaticResource Labelfont}" IsVisible="True" />
<StackLayout Grid.Row="3" Grid.Column="1" Orientation="Horizontal" Spacing="0">
<Image Source="statusUnresolved.png" HorizontalOptions="Center"
VerticalOptions="Center" HeightRequest="40" Opacity="{Binding StatusUnresolvedOpacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="statusUnresolved.png"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="3" Grid.Column="2" Orientation="Horizontal" Spacing="4">
<Image Source="statusInProgress.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="{Binding StatusInProgressOpacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="statusInProgress.png"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="3" Grid.Column="3" Orientation="Horizontal" Spacing="4">
<Image Source="statusDone.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="{Binding StatusDoneOpacity}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnStatusClickedCommand}" CommandParameter="statusDone.png"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</Grid>
<!--Date Created-->
<Label Text="TIME AND DATE: " Style="{StaticResource Labelfont}" TextColor="White" />
<Frame OutlineColor="#FBB040" BackgroundColor="Black" Padding="2">
<StackLayout Orientation="Horizontal" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" Spacing="0" Margin="0" Padding="0"
BackgroundColor="Black" HeightRequest="40">
<Label Text=" " Style="{StaticResource Labelfont}" TextColor="White" BackgroundColor="Black"
Margin="1" />
<Label Text="{Binding CreatedEx, Converter={StaticResource DateToTextConverter}}"
Style="{StaticResource Labelfont}" TextColor="White" BackgroundColor="Black"
VerticalOptions="Center" />
</StackLayout>
</Frame>
<!--REPORTED BY-->
<Label Text="REPORTED BY: " Style="{StaticResource Labelfont}" TextColor="White" />
<Frame OutlineColor="#FBB040" BackgroundColor="Black" Padding="2">
<StackLayout Orientation="Horizontal" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" Spacing="0" Padding="1" BackgroundColor="Black"
HeightRequest="40">
<Label Text=" " Style="{StaticResource Labelfont}" TextColor="White" BackgroundColor="Black" />
<Label Text="{Binding CreatedByEx}" Style="{StaticResource Labelfont}"
TextColor="White" BackgroundColor="Black" VerticalOptions="Center" />
</StackLayout>
</Frame>
<!--Map View-->
<Grid>
<Grid.BindingContext>
<maps:TkMapPageModel/>
</Grid.BindingContext>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Label Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"
Text="Tap and hold on map to set/move pin" Font="Large" />
<StackLayout Grid.Column="1" Grid.Row="1" VerticalOptions="FillAndExpand">
<RelativeLayout x:Name="MapRelativeLayout" VerticalOptions="FillAndExpand" HeightRequest="920" WidthRequest="300" />
</StackLayout>
<StackLayout Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" Orientation="Vertical" Spacing="0">
<Label Text="{Binding MapText}" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White" />
</StackLayout>
</Grid>
<Button Text="Submit"
HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand" Command="{Binding SubmitCommand}"
BackgroundColor="#FBB040" />
</StackLayout>
</ScrollView>
<!--Bottom Navigation Bar-->
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<StackLayout Grid.ColumnSpan="3" Grid.Row="1" Orientation="Horizontal"
HorizontalOptions="FillAndExpand" Spacing="5" BackgroundColor="White">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" BackgroundColor="#FBB040">
<Image Source="photo2.png" WidthRequest="100" HeightRequest="100" HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
</Image>
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" BackgroundColor="#FBB040">
<Image Source="photo2.png" WidthRequest="100" HeightRequest="100" HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
</Image>
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" BackgroundColor="#FBB040">
<Image Source="showmap.png" WidthRequest="100" HeightRequest="60" HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand">
</Image>
</StackLayout>
</StackLayout>
</Grid>
</Grid>
当我重复时,它在从imageGallerypageModel添加时起作用,而不是来自其他类的IssuePageModel
public class ImageGalleryControl : ScrollView
{
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create<ImageGalleryControl, IList>(
view => view.ItemsSource,
default(IList),
BindingMode.TwoWay,
propertyChanging: (bindableObject, oldValue, newValue) => {
((ImageGalleryControl)bindableObject).ItemsSourceChanging();
},
propertyChanged: (bindableObject, oldValue, newValue) => {
((ImageGalleryControl)bindableObject).ItemsSourceChanged(bindableObject, oldValue, newValue);
}
);
public IList ItemsSource
{
get
{
return (IList)GetValue(ItemsSourceProperty);
}
set
{
SetValue(ItemsSourceProperty, value);
}
}
Images
在您的模型中是一个ObservableCollection
,它很像列表。当您添加图像时,您不会因为不更改集合而不会点击set
,因此您正在添加到现有集合中。这是正确的方法... ObservableCollection
包含INotifyCollectionChanged
接口,这意味着您可以订阅并收听更改的CollectionChanged
事件。在任何物品中使用XAML绑定时,应该自动为您聆听和处理此事件,但在您自己的代码后面或任何地方的代码中,您很可能需要执行此操作。
请记住,收集参考也可以更改,因此您也需要为此处理。这是如何正确处理从模型到模型的ObservableCollection
的示例。
public class ExampleModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> names = new ObservableCollection<string>();
public ObservableCollection<string> Names
{
get => names;
set
{
names = value;
//Only called if I change the collection reference i.e. make a new ObservableCollection or assign it to another exising reference.
//Not called adding or removing items from existing collection.
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Names)));
}
}
}
....
public class ExampleViewModel : INotifyPropertyChanged
{
private readonly ExampleModel ExampleModel;
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> names = new ObservableCollection<string>();
public ExampleViewModel()
{
ExampleModel = new ExampleModel();
ExampleModel.PropertyChanged += ExampleModel_PropertyChanged;
Names = ExampleModel.Names;
if (Names != null) Names.CollectionChanged += Names_CollectionChanged;
}
private void ExampleModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ExampleModel.Names):
//Here we reassign the entire collection if it changes.
if (Names != null) Names.CollectionChanged -= Names_CollectionChanged;
Names = ExampleModel.Names;
if (Names != null) Names.CollectionChanged += Names_CollectionChanged;
break;
}
}
private void Names_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
foreach (var item in e.OldItems) Names.Remove((string)item);
foreach (var item in e.NewItems) Names.Add((string)item);
}
public ObservableCollection<string> Names
{
get => names;
set
{
names = value;
//Only called if I change the collection reference i.e. make a new ObservableCollection or assign it to another exising reference.
//Not called adding or removing items from existing collection.
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Names)));
}
}
}
注意:此示例只是为了使您更清楚地了解它的工作原理,并且可能不是实施两者的最清洁方法。如果知道它们都是观察到的,那很好,但是在最小的时候,我们可能应该假设它们是可以静止不动的,并且对此有些不同。无论哪种方式...但是您需要在代码中手动处理它,而XAML则在绑定到项目库时应为您处理。