简体   繁体   English

ImageGallery不会从其他班级更新

[英]ImageGallery won't update from other class

So I'm attempting to download an image in byte from a server, but the image won't display. 因此,我尝试从服务器以字节为单位下载图像,但该图像不会显示。 I get a proper byte-Array and rezise it. 我得到一个适当的字节数组并将其调整大小。 It works adding Picture from the imagegallerypagemodel but doesn't work when adding them from the IssuePageModel. 它可以从imagegallerypagemodel添加图片,但是从IssuePageModel添加它们时不起作用。 So I suspect either the class is instanced wrongly or notifyproperty doesn't work. 因此,我怀疑该类被错误地实例化或notifyproperty无法正常工作。 I've attempted to only add the relevant parts, but can add anything missing. 我尝试仅添加相关部分,但可以添加任何缺少的内容。

The Collection 集合

 public class ImageGalleryPageModel
    {
        public ObservableCollection<ImageModel> Images
        {
            get { return images; }
        }

    private ObservableCollection<ImageModel> images = new ObservableCollection<ImageModel>();

This works adding the Pictures from this class 这可以添加此类中的图片

 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 });
            }
        }

Then I load the issuepagemodel for a second time, here is the instance of the imagegallerypagemodel 然后我第二次加载issuepagemodel,这是imagegallerypagemodel的实例

public class IssuePageModel : FreshBasePageModel, INotifyPropertyChanged
{


 public ImageGalleryPageModel ImageGalleryViewModel { get; set; } = new ImageGalleryPageModel();

Then I download the images and put them into the Collection, the notifyproperty is triggered, I can see when debugging it steps onto the get, but can't see it on the set part though. 然后,我下载图像并将其放入Collection中,并触发notifyproperty,我可以在调试它进入get时看到它,但是在set部分却看不到它。

 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 });
            }
        }

Entire Xaml 整个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="    &lt;   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>

And as I repeat, it works when adding from the imagegallerypagemodel but not from the other class IssuePageModel 正如我重复的,当从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 in your model is an ObservableCollection which works a lot like a list. 模型中的Images是一个ObservableCollection ,其工作原理非常类似于列表。 When you add an image you're not going to hit the set because you're not changing the collection, you're adding to the existing collection. 当您添加图像时,因为您没有更改收藏set而不会打中该set ,而是要添加到现有收藏集中。 This is the correct way... The ObservableCollection contains the INotifyCollectionChanged interface which means there's a CollectionChanged event you can subscribe to and listen for changes. 这是正确的做法...的ObservableCollection包含INotifyCollectionChanged接口,这意味着有一个CollectionChanged您可以订阅并监听变化事件。 When using XAML binding in any itemssource it should automatically be listening and handling this event for you but in the code behind or anywhere in your own code you will most likely need to do this. 在任何itemsource中使用XAML绑定时,它应该自动为您侦听和处理此事件,但是您很可能需要在您自己代码的后面或任何地方的代码中执行此操作。

Just remember that the collection reference can change also so you need to handle for that as well. 请记住,集合引用也可以更改,因此您也需要进行处理。 Here's an example of how to properly handle the ObservableCollection from model to model. 这是一个如何正确处理模型之间的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)));
        }
    }

}

NOTE: This example is just to give you a clearer idea of how it works and may not be the cleanest way to implement the two. 注意:此示例只是为了使您更清楚地了解其工作原理,可能不是实现两者的最简洁的方法。 If know they are both ObservableCollections then that's fine but at min we should probably assume they are IEnumerable and handle this slightly differently. 如果知道它们都是ObservableCollections,那就很好了,但至少我们应该假设它们是IEnumerable的,并且处理方式略有不同。 Either way... But you need to handle it manually in your code and the XAML should handle this for you when binding to an ItemsSource. 无论哪种方式,但是您都需要在代码中手动处理它,并且XAML在绑定到ItemsSource时应该为您处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM