コード例 #1
0
 public int InsertEntityImage(EntityImage model)
 {
     using (PetaPoco.Database context = new PetaPoco.Database("DefaultConnection"))
     {
         return((int)context.Insert(model));
     }
 }
コード例 #2
0
        public DtoActionResult Add(EntityImage image)
        {
            var actionResult = new DtoActionResult();

            var validationResult = Validate(image, true);

            if (validationResult.Success)
            {
                _uow.ImageRepository.Insert(image);
                _uow.Save();
                actionResult.Success = true;
                actionResult.Id      = image.Id;
                var defaultProfile = SeedDefaultImageProfile(image.Id);
                defaultProfile.ImageId = image.Id;
                new ServiceImageProfile().Add(defaultProfile);
            }
            else
            {
                return(new DtoActionResult()
                {
                    ErrorMessage = validationResult.ErrorMessage
                });
            }

            return(actionResult);
        }
コード例 #3
0
ファイル: create.aspx.cs プロジェクト: theopenem/Toems
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            var image = new EntityImage
            {
                Name        = txtImageName.Text,
                Environment = ddlEnvironment.Text,
                Description = txtImageDesc.Text,
                Protected   = chkProtected.Checked,
                IsVisible   = chkVisible.Checked,
                Enabled     = true,
            };

            image.Type = ddlEnvironment.Text == "winpe" ? "File" : ddlImageType.Text;

            var result = Call.ImageApi.Post(image);

            if (result.Success)
            {
                EndUserMessage = "Successfully Added Image";
                Response.Redirect("~/views/images/general.aspx?imageId=" + result.Id);
            }
            else
            {
                EndUserMessage = result.ErrorMessage;
            }
        }
コード例 #4
0
ファイル: ImageListBoxItem.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageListBoxItem"/> class with the
        /// specified <see cref="EntityImage"/> content.</summary>
        /// <param name="image">
        /// The <see cref="EntityImage"/> that is the initial value for the <see
        /// cref="ContentControl.Content"/> property.</param>

        public ImageListBoxItem(EntityImage image) : this()
        {
            Content = image;
            if (image != null)
            {
                ToolTip = image.Id;
            }
        }
コード例 #5
0
        /// <summary>
        /// Handles the <see cref="ButtonBase.Click"/> event for the "Add Image" <see
        /// cref="Button"/>.</summary>
        /// <param name="sender">
        /// The <see cref="Object"/> where the event handler is attached.</param>
        /// <param name="args">
        /// A <see cref="RoutedEventArgs"/> object containing event data.</param>
        /// <remarks><para>
        /// <b>OnImageAdd</b> shows an error message if the "Image File" list view is empty.
        /// Otherwise, <b>OnImageAdd</b> displays a <see cref="Dialog.ChangeIdentifier"/> dialog,
        /// followed by a <see cref="Dialog.ChangeImage"/> dialog, allowing the user to define a new
        /// image. The new image copies the properties of the selected image, if any; otherwise, it
        /// is created with default properties.
        /// </para><para>
        /// If the user confirmed both dialogs, <b>OnImageAdd</b> adds the new image to the <see
        /// cref="ImageListBox"/> and to the current <see cref="ImageSection"/>, and sets the <see
        /// cref="SectionTabItem.DataChanged"/> flag.</para></remarks>

        private void OnImageAdd(object sender, RoutedEventArgs args)
        {
            args.Handled = true;

            // abort if there are no image files
            if (FileList.Items.Count == 0)
            {
                MessageBox.Show(MainWindow.Instance,
                                Global.Strings.DialogImageFileNone, Global.Strings.TitleImageFileNone,
                                MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            // ask user for new image ID
            var images = MasterSection.Instance.Images.Collection;
            var dialog = new Dialog.ChangeIdentifier("image-id",
                                                     Global.Strings.TitleImageIdEnter, images.ContainsKey, false);

            dialog.Owner = MainWindow.Instance;
            if (dialog.ShowDialog() != true)
            {
                return;
            }

            // retrieve new image ID
            string id = String.Intern(dialog.Identifier);

            // create new image based on selected image, if any
            var         selection = ImageList.SelectedItem as ImageListBoxItem;
            EntityImage image     = (selection == null ? new EntityImage() :
                                     (EntityImage)((EntityImage)selection.Content).Clone());

            image.Id = id;

            // let user make changes to new image
            var imageDialog = new Dialog.ChangeImage(image)
            {
                Owner = MainWindow.Instance
            };

            if (imageDialog.ShowDialog() != true)
            {
                return;
            }

            // add image to section table
            images.Add(id, image);

            // update list box and select new item
            var item  = new ImageListBoxItem(image);
            int index = ImageList.Insert(item);

            ImageList.SelectAndShow(index);

            // broadcast data changes
            EnableListButtons();
            SectionTab.DataChanged = true;
        }
コード例 #6
0
        /// <summary>
        /// Copies and counts all image frames for the specified <see cref="EntityClass"/>, starting
        /// at the specified catalog tile.</summary>
        /// <param name="copying">
        /// <c>true</c> to perform the actual copy; <c>false</c> to set catalog indices and count
        /// animation frames only.</param>
        /// <param name="entityClass">
        /// The <see cref="EntityClass"/> whose frames to copy.</param>
        /// <param name="index">
        /// The catalog tile index where to copy the first frame of the specified <paramref
        /// name="entityClass"/>. On return, this parameter contains the tile index following the
        /// last frame.</param>
        /// <returns>
        /// The <see cref="EntityClass.FrameCount"/> of the specified <paramref name="entityClass"/>
        /// if its <see cref="EntityClass.ImageAnimation"/> value does not equal <see
        /// cref="AnimationMode.None"/>; otherwise, one. This value is always at least one.
        /// </returns>
        /// <remarks><para>
        /// <b>CopyEntityClass</b> sets the <see cref="EntityClass.FrameIndex"/> property of the
        /// specified <paramref name="entityClass"/> to the specified <paramref name="index"/>.
        /// </para><para>
        /// If the <see cref="EntityClass.FrameCount"/> of the specified <paramref
        /// name="entityClass"/> is zero or if copying fails, <b>CopyEntityClass</b> sets
        /// <b>FrameIndex</b> to zero and returns a value of one. This will cause map views to show
        /// an "invalid" icon for <paramref name="entityClass"/>.</para></remarks>

        private int CopyEntityClass(bool copying, EntityClass entityClass, ref int index)
        {
            // require at least one frame per entity
            if (entityClass.FrameCount == 0)
            {
                entityClass.FrameIndex = 0;
                return(1);
            }

            // set catalog tile index
            entityClass.FrameIndex = index;

            // one catalog tile per frame used
            index += entityClass.FrameCount;

            // determine animation frame count
            bool animation       = (entityClass.ImageAnimation != AnimationMode.None);
            int  animationFrames = (animation ? entityClass.FrameCount : 1);

            // quit immediately if no copying desired
            if (!copying)
            {
                return(animationFrames);
            }

            // overlay image frames with identical indices
            foreach (ImageStackEntry entry in entityClass.ImageStack)
            {
                EntityImage image = entry.Image.Value;
                if (image == null)
                {
                    continue;
                }

                // iterate over all catalog tiles for this class
                int frameCount = image.Frames.Count;
                for (int i = 0; i < entityClass.FrameCount; i++)
                {
                    // copy single frame if specified, else current frame
                    int        sourceIndex = (entry.SingleFrame < 0 ? i : entry.SingleFrame);
                    ImageFrame frame       = image.Frames[sourceIndex % frameCount];

                    // store entity class for current tile index
                    int targetIndex = entityClass.FrameIndex + i;
                    this._catalogClasses[targetIndex] = entityClass;

                    // copy to tile, default to "invalid" icon on failure
                    if (!CopyImageFrame(targetIndex, entry, frame))
                    {
                        entityClass.FrameIndex = 0;
                        return(1);
                    }
                }
            }

            return(animationFrames);
        }
コード例 #7
0
        /// <summary>
        /// Draws the <see cref="ImageStack"/> to the specified rectangle.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the drawing.</param>
        /// <param name="target">
        /// The drawing region within <paramref name="context"/>, in device-independent pixels.
        /// </param>
        /// <returns>
        /// <c>true</c> if all <see cref="ImageStack"/> elements were drawn without errors;
        /// otherwise, <c>false</c>.</returns>
        /// <remarks>
        /// <b>DrawImageStack</b> draws the selected <see cref="Frames"/> of all <see
        /// cref="ImageStack"/> elements to the specified <paramref name="target"/> rectangle within
        /// the specified <paramref name="context"/>.</remarks>

        private bool DrawImageStack(DrawingContext context, Rect target)
        {
            Debug.Assert(ImageStack.Count == Frames.Count);

            // fail if no images are available
            if (ImageStack.Count == 0)
            {
                return(false);
            }

            // draw selected frames of all images
            for (int i = 0; i < ImageStack.Count; i++)
            {
                ImageStackEntry entry = ImageStack[i];

                // quit on first unavailable image
                EntityImage image = entry.Image.Value;
                if (image == null)
                {
                    return(false);
                }

                // determine selected frame
                int        frameIndex = Frames[i] % image.Frames.Count;
                ImageFrame frame      = image.Frames[frameIndex];

                // quit on first unavailable bitmap
                if (frame.Source.Value == null)
                {
                    return(false);
                }

                // get desired image scaling, unless disabled
                ImageScaling scalingX = ImageScaling.None, scalingY = ImageScaling.None;
                if (!entry.UseUnscaled)
                {
                    scalingX = image.ScalingX;
                    scalingY = image.ScalingY;
                }

                // draw frame with specified display parameters
                if (!ImageUtility.DrawOutlineFrame(context, Brushes.Black, target,
                                                   frame.Source.Value.Bitmap, frame.Bounds, Polygon, scalingX, scalingY,
                                                   entry.ColorShift, entry.Offset, entry.ScalingVector))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #8
0
ファイル: ChangeFrame.xaml.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeFrame"/> class with the specified
        /// <see cref="ImageStackEntry"/>.</summary>
        /// <param name="entry">
        /// The <see cref="ImageStackEntry"/> whose <see cref="ImageStackEntry.SingleFrame"/> value
        /// to change.</param>
        /// <exception cref="ArgumentException">
        /// <paramref name="entry"/> contains an <see cref="ImageStackEntry.Image"/> that is a null
        /// reference or contains less than two <see cref="EntityImage.Frames"/>.</exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="entry"/> is a null reference.</exception>
        /// <remarks>
        /// The data of the specified <paramref name="entry"/> may be changed in the dialog, as
        /// indicated by the value of the <see cref="DataChanged"/> property.</remarks>

        public ChangeFrame(ImageStackEntry entry)
        {
            if (entry == null)
            {
                ThrowHelper.ThrowArgumentNullException("entry");
            }

            EntityImage image = entry.Image.Value;

            if (image == null)
            {
                ThrowHelper.ThrowArgumentExceptionWithFormat("entry",
                                                             Tektosyne.Strings.ArgumentSpecifiesInvalid, "Image");
            }

            if (image.Frames.Count < 2)
            {
                ThrowHelper.ThrowArgumentExceptionWithFormat("entry",
                                                             Global.Strings.ArgumentSpecifiesSingleFrame, "Image");
            }

            this._entry = entry;
            InitializeComponent();
            Title += image.Id;

            // prepare list box for image frames
            FrameList.Polygon = MasterSection.Instance.Areas.MapGrid.Element;

            // use image scaling unless disabled
            if (!entry.UseUnscaled)
            {
                FrameList.ScalingX = image.ScalingX;
                FrameList.ScalingY = image.ScalingY;
            }

            // add image frames to list box
            Debug.Assert(image.Frames.Count >= 2);
            foreach (ImageFrame frame in image.Frames)
            {
                FrameList.Items.Add(new ImageListBoxItem(frame));
            }

            // select initial item in Frames list box
            int index = Math.Max(0, this._entry.SingleFrame);

            FrameList.SelectAndShow(Math.Min(index, FrameList.Items.Count - 1));
        }
コード例 #9
0
        public DtoActionResult Post(EntityImage image)
        {
            var result = _imageService.Add(image);

            if (result.Success)
            {
                var auditLog = new EntityAuditLog();
                auditLog.ObjectType = "Image";
                auditLog.ObjectId   = result.Id;
                auditLog.ObjectName = image.Name;
                auditLog.ObjectJson = JsonConvert.SerializeObject(image);
                auditLog.UserId     = _userId;
                auditLog.AuditType  = EnumAuditEntry.AuditType.Create;
                _auditLogService.AddAuditLog(auditLog);
            }
            return(result);
        }
コード例 #10
0
        public DtoActionResult Update(EntityImage image)
        {
            var u = GetImage(image.Id);

            if (u == null)
            {
                return new DtoActionResult {
                           ErrorMessage = "Image Not Found", Id = 0
                }
            }
            ;

            var actionResult = new DtoActionResult();

            var updateFolderName = u.Name != image.Name;
            var oldName          = u.Name;
            var validationResult = Validate(image, false);

            if (validationResult.Success)
            {
                _uow.ImageRepository.Update(image, u.Id);

                _uow.Save();

                actionResult.Id = image.Id;
                if (updateFolderName)
                {
                    actionResult.Success = new FilesystemServices().RenameImageFolder(oldName, image.Name);
                }
                else
                {
                    actionResult.Success = true;
                }
            }
            else
            {
                return(new DtoActionResult()
                {
                    ErrorMessage = validationResult.ErrorMessage
                });
            }
            return(actionResult);
        }
コード例 #11
0
        public DtoActionResult Put(int id, EntityImage image)
        {
            image.Id = id;
            var result = _imageService.Update(image);

            if (result == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }
            if (result.Success)
            {
                var auditLog = new EntityAuditLog();
                auditLog.ObjectType = "Image";
                auditLog.ObjectId   = result.Id;
                auditLog.ObjectName = image.Name;
                auditLog.ObjectJson = JsonConvert.SerializeObject(image);
                auditLog.UserId     = _userId;
                auditLog.AuditType  = EnumAuditEntry.AuditType.Update;
                _auditLogService.AddAuditLog(auditLog);
            }
            return(result);
        }
コード例 #12
0
        public DtoValidationResult Validate(EntityImage image, bool isNew)
        {
            var validationResult = new DtoValidationResult {
                Success = true
            };

            if (string.IsNullOrEmpty(image.Name) || !image.Name.All(c => char.IsLetterOrDigit(c) || c == '_' || c == '-' || c == ' '))
            {
                validationResult.Success      = false;
                validationResult.ErrorMessage = "Image Name Is Not Valid";
                return(validationResult);
            }

            if (isNew)
            {
                if (_uow.ImageRepository.Exists(h => h.Name == image.Name))
                {
                    validationResult.Success      = false;
                    validationResult.ErrorMessage = "A Image With This Name Already Exists";
                    return(validationResult);
                }
            }
            else
            {
                var original = _uow.ImageRepository.GetById(image.Id);
                if (original.Name != image.Name)
                {
                    if (_uow.ImageRepository.Exists(h => h.Name == image.Name))
                    {
                        validationResult.Success      = false;
                        validationResult.ErrorMessage = "A Image With This Name Already Exists";
                        return(validationResult);
                    }
                }
            }

            return(validationResult);
        }
コード例 #13
0
        public JsonResult UploadImageForCommonInfo(string imageData, string section)
        {
            string fileName = Guid.NewGuid().ToString();
            string url      = "";
            string message  = "";

            try
            {
                byte[] data = Convert.FromBase64String(imageData);
                System.IO.FileStream file = System.IO.File.Create(Server.MapPath("~/FileUpload/") + fileName + ".jpg");

                url = "/FileUpload/" + fileName + ".jpg";
                file.Write(data, 0, data.Length);
                file.Close();

                if (section == "6")
                {
                    EntityImage image = new EntityImage();

                    image.SectionID = 6;
                    image.Url       = url;

                    Services.GetInstance.InsertEntityImage(image);
                }
                else if (section == "0couple")
                {
                    CommonInfo commonInfo = new CommonInfo();

                    commonInfo = Services.GetInstance.GetCommonInfoData();
                    commonInfo.CouplePictureUrl = url;

                    Services.GetInstance.UpdateCommonInfoData(commonInfo);
                }
                else if (section == "0gift")
                {
                    CommonInfo commonInfo = new CommonInfo();

                    commonInfo = Services.GetInstance.GetCommonInfoData();
                    commonInfo.GiftRegistryImageUrl = url;

                    Services.GetInstance.UpdateCommonInfoData(commonInfo);
                }
                else if (section == "1")
                {
                    EntityImage image = new EntityImage();

                    image.SectionID = 1;
                    image.Url       = url;
                    image.thumbnail = url;

                    Services.GetInstance.InsertEntityImage(image);
                }

                else if (section == "4")
                {
                    EntityImage image = new EntityImage();

                    image.SectionID = 4;
                    image.thumbnail = url;

                    Services.GetInstance.InsertEntityImage(image);
                }
                else if (section == "5")
                {
                    EntityImage image = new EntityImage();

                    image.SectionID = 5;
                    image.thumbnail = url;

                    Services.GetInstance.InsertEntityImage(image);
                }

                message = "Image Uploaded Successfully!";
            }
            catch (Exception ex)
            {
                message = ex.Message.ToString();
            }

            return(Json(new { Message = message }, JsonRequestBehavior.AllowGet));
        }
コード例 #14
0
ファイル: ImageListBoxItem.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Renders the visual content of the <see cref="ImageListBoxItem"/>.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the rendering.</param>
        /// <remarks><para>
        /// <b>OnRender</b> calls the base class implementation of <see cref="UIElement.OnRender"/>,
        /// and then attempts to display the current <see cref="ContentControl.Content"/> of the
        /// <see cref="ImageListBoxItem"/>, depending on its type:
        /// </para><list type="bullet"><item>
        /// If the element is an <see cref="EntityImage"/>, its first image frame is drawn above a
        /// text label showing its identifier.
        /// </item><item>
        /// If the element is an <see cref="ImageFrame"/>, the frame is drawn without a label.
        /// </item><item>
        /// If the element is a <see cref="RectI"/>, the corresponding region of the <see
        /// cref="ImageListBox.FrameBitmap"/> is drawn without a label.
        /// </item></list><para>
        /// If the element is of any other type, or if an error occurs, the "invalid" icon returned
        /// by <see cref="Images.Invalid"/> is drawn instead.</para></remarks>

        protected override void OnRender(DrawingContext context)
        {
            base.OnRender(context);

            // default to base class if not in an ImageListBox
            ImageListBox listBox = Parent as ImageListBox;

            if (listBox == null)
            {
                return;
            }

            // get drawing parameters of containing ImageListBox
            WriteableBitmap bitmap = listBox.FrameBitmap;
            ImageScaling    scalingX = listBox.ScalingX, scalingY = listBox.ScalingY;

            // source within bitmap and target within context
            RectI source = RectI.Empty;
            Rect  target = new Rect(0, 0, ActualWidth, ActualHeight);

            /*
             * The default Background brush of a ListBoxItem is transparent, meaning that an item
             * will not register clicks on anything but the non-transparent image and text label.
             *
             * This is very inconvenient, so we always draw a fully opaque background. We use the
             * ListBox.Background brush for regular items, and the system-defined HighlightBrush
             * for selected items. The Foreground brush changes automatically as appropriate.
             *
             * NOTE: The HighlightBrush must be drawn explicitly anyway, or else the Foreground
             * of a selected item would be invisible against the Background of the ListBox!
             */

            Brush background = (listBox.SelectedItem == this ?
                                SystemColors.HighlightBrush : listBox.Background);

            context.DrawRectangle(background, null, target);

            // check which content we're drawing
            if (Content is RectI)
            {
                source = (RectI)Content;
            }
            else
            {
                ImageFrame frame = Content as ImageFrame;
                if (frame == null)
                {
                    EntityImage image = Content as EntityImage;
                    if (image == null)
                    {
                        goto failure;
                    }

                    // get first image frame and scaling
                    frame    = image.Frames[0];
                    scalingX = image.ScalingX;
                    scalingY = image.ScalingY;

                    // compute bounds of image label
                    Point textLocation = new Point(0, ActualHeight - this._labelHeight);
                    Size  textSize     = new Size(ActualWidth, this._labelHeight);

                    // reduce image bounds accordingly
                    target.Height -= textSize.Height;

                    // draw text for image label
                    FormattedText text = FormatLabel(image.Id, textSize);
                    context.DrawText(text, textLocation);
                }

                // final sanity check for valid image frame
                if (frame == null || frame.Source.Value == null)
                {
                    goto failure;
                }

                // draw image frame with associated bitmap
                bitmap = frame.Source.Value.Bitmap;
                source = frame.Bounds;
            }

            // draw specified rectangle with desired bitmap & scaling
            if (ImageUtility.DrawOutlineFrame(context, Foreground, target, bitmap, source,
                                              listBox.Polygon, scalingX, scalingY, ColorVector.Empty, PointI.Empty, PointI.Empty))
            {
                return;
            }

failure:
            // draw "invalid" icon on failure
            ImageUtility.DrawInvalidIcon(context, Foreground, target, listBox.Polygon);
        }
コード例 #15
0
ファイル: ChangeImage.xaml.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeImage"/> class with the specified
        /// <see cref="EntityImage"/>.</summary>
        /// <param name="image">
        /// The <see cref="EntityImage"/> whose data to change.</param>
        /// <exception cref="PropertyValueException">
        /// The current <see cref="ImageSection"/> contains an empty <see
        /// cref="ImageSection.ImageFiles"/> collection.</exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="image"/> is a null reference.</exception>
        /// <remarks>
        /// The data of the specified <paramref name="image"/> may be changed in the dialog, as
        /// indicated by the value of the <see cref="DataChanged"/> property.</remarks>

        public ChangeImage(EntityImage image)
        {
            if (image == null)
            {
                ThrowHelper.ThrowArgumentNullException("image");
            }

            // require non-empty ImageFiles for simplicity
            if (MasterSection.Instance.Images.ImageFiles.Count == 0)
            {
                ThrowHelper.ThrowPropertyValueException(
                    "MasterSection.Instance.Images.ImageFiles", Tektosyne.Strings.PropertyEmpty);
            }

            this._image = image;
            InitializeComponent();
            Title += image.Id;

            // initialize frame control buttons
            AddFrameButton.ShowSymbol(Symbols.BoxEmpty);
            RemoveFrameButton.ShowSymbol(Symbols.BoxCrossed);
            MoveLeftButton.ShowSymbol(Symbols.ArrowLeft);
            MoveRightButton.ShowSymbol(Symbols.ArrowRight);

            // set maximum ranges for frame dimensions
            LeftUpDown.Maximum   = Int32.MaxValue;
            TopUpDown.Maximum    = Int32.MaxValue;
            WidthUpDown.Minimum  = 1;
            WidthUpDown.Maximum  = Int32.MaxValue;
            HeightUpDown.Minimum = 1;
            HeightUpDown.Maximum = Int32.MaxValue;

            // add image files to combo box
            foreach (string id in MasterSection.Instance.Images.ImageFiles.Keys)
            {
                FileCombo.Items.Add(id);
            }

            // add animation options to combo boxes
            AnimationCombo.ItemsSource = Enum.GetValues(typeof(AnimationMode));
            SequenceCombo.ItemsSource  = Enum.GetValues(typeof(AnimationSequence));

            // add scaling options to combo boxes
            var scalingValues = Enum.GetValues(typeof(ImageScaling));

            ScalingXCombo.ItemsSource = scalingValues;
            ScalingYCombo.ItemsSource = scalingValues;

            // set animation & scaling options
            AnimationCombo.SelectedItem = image.Animation;
            SequenceCombo.SelectedItem  = image.Sequence;
            ScalingXCombo.SelectedItem  = image.ScalingX;
            ScalingYCombo.SelectedItem  = image.ScalingY;

            // enable sequence control if animation enabled
            SequenceCombo.IsEnabled = (image.Animation != AnimationMode.None);

            // initialize list box parameters
            FrameList.Polygon  = MasterSection.Instance.Areas.MapGrid.Element;
            FrameList.ScalingX = image.ScalingX;
            FrameList.ScalingY = image.ScalingY;

            // add default rectangle if none defined
            if (image.Frames.Count == 0)
            {
                image.Frames.Add(CreateFrame());
            }

            // add frame bounds to list box
            foreach (ImageFrame frame in image.Frames)
            {
                RectI bounds = frame.Bounds;

                // correct any illegal location values
                int maxPoint = SimpleXml.MaxPointIValue;
                int left     = Math.Max(0, Math.Min(maxPoint, bounds.Left));
                int top      = Math.Max(0, Math.Min(maxPoint, bounds.Top));

                // correct any illegal size values
                int maxSize = SimpleXml.MaxSizeIValue;
                int width   = Math.Max(1, Math.Min(maxSize, bounds.Width));
                int height  = Math.Max(1, Math.Min(maxSize, bounds.Height));

                // add frame with corrected bounds to list box
                RectI      newBounds = new RectI(left, top, width, height);
                ImageFrame newFrame  = new ImageFrame(frame);
                newFrame.Bounds = newBounds;

                FrameList.Items.Add(new ImageListBoxItem(newFrame));

                // add invalid file identifier to combo box
                string fileId = newFrame.Source.Key;
                if (!String.IsNullOrEmpty(fileId) && !FileCombo.Items.Contains(fileId))
                {
                    FileCombo.Items.Add(fileId);
                }
            }

            // disable Remove if only one frame defined
            RemoveFrameButton.IsEnabled = (FrameList.Items.Count > 1);

            // animate dashed outline of frame marker
            DoubleAnimation animation = new DoubleAnimation(10, 0, Duration.Automatic);

            animation.RepeatBehavior = RepeatBehavior.Forever;
            FrameMarker.BeginAnimation(Shape.StrokeDashOffsetProperty, animation);

            // construction completed
            this._initialized = true;
        }