Click here to Skip to main content
15,893,668 members
Articles / Desktop Programming / WPF

WPF Amazon Explorer Using 3D

Rate me:
Please Sign up or sign in to vote.
4.95/5 (54 votes)
27 Feb 2008CPOL18 min read 187.8K   1.9K   127  
WPF Amazon Explorer Using 3D
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Reflection;

using AmazonService;

namespace Explorer3D
{
    /// <summary>
    /// This Window contains a FlowDocumentPageViewer and a FlowDocument control.
    /// The FlowDocument is populated with some static content and some dynamic
    /// content to represent a single Details (Amazon detail) item. A combination
    /// of LINQ and reflection is used in order to display the fields for a given
    /// Details (Amazon detail) item. Only those that are not arrays and not null are 
    /// shown within the FlowDocument
    /// </summary>
    public partial class FlowDocumentWindow : Window
    {
        #region Instance Fields
        public Details AmazonDetail { get; set; }
        private BlockUIContainer uiCont;
        private bool doneImage=false;
        #endregion

        #region Ctor
        public FlowDocumentWindow()
        {
            this.InitializeComponent();
        }
        #endregion

        #region Public methods

        /// <summary>
        /// This method is called by the <see cref="ExplorerWindow">ExplorerWindow</see>
        /// when one of the 3d Amazon items is clicked. This method creates various Paragraphs
        /// and BlockUIContainers to represent the current Details (Amazon detail)
        /// </summary>
        public void CreateDocumentFromDetail()
        {

            Details det = AmazonDetail;
            Type amazonType = det.GetType();
            //get all public and instance fields only
            PropertyInfo[] props = amazonType.GetProperties(
                BindingFlags.Public | BindingFlags.Instance);
            //now use some LINQ with some added reflection for good measure
            //to obtain the fields from the Amazon details that arent null
            var nonNullProps  =     (   from prop in props where
                                        prop.GetValue(det, null) != null &&
                                        !prop.GetValue(det, null).ToString().EndsWith("[]")
                                        select new AmazonParameterDetail
                                             {
                                                 PropertyName = prop.Name,
                                                 PropertyValue = prop.GetValue(det, null).ToString()
                                             }
                                    );

            SolidColorBrush headerBrsh = this.TryFindResource("headerBrush") as SolidColorBrush;

            try
            {

                //create a individual header line and actual value line for each of the not empty
                //amazon values
                foreach (AmazonParameterDetail nonNullprop in nonNullProps)
                {

                    //if the property is an image, display and image, otherwise a link
                    if (nonNullprop.PropertyName.ToLower().Contains("image"))
                    {
                        if (!doneImage)
                        {
                            CreateParaGraph(headerBrsh, nonNullprop);
                        }
                    }
                    else
                    {
                        CreateParaGraph(headerBrsh, nonNullprop);
                    }

                    //Treat Http ones differently, create hyperlink for them
                    if (nonNullprop.PropertyValue.ToLower().StartsWith("http"))
                    {
                        
                        //if the property is an image, display and image, otherwise a link
                        if (nonNullprop.PropertyName.ToLower().Contains("image"))
                        {
                            if (!doneImage)
                            {
                                //img.Source = new BitmapImage(new Uri(nonNullprop.PropertyValue));
                                if (Uri.IsWellFormedUriString(nonNullprop.PropertyValue, UriKind.Absolute))
                                {
                                    #region Create Image
                                    //setup the Table
                                    Table tab = new Table();
                                    tab.Padding = new Thickness(5);
                                    tab.Foreground = new SolidColorBrush(Colors.White);
                                    tab.FontWeight = FontWeights.Bold;
                                    tab.FontSize = 10;

                                    //setup the Table Column
                                    TableColumn tc = new TableColumn();
                                    tc.Width = new GridLength(60);
                                    tab.Columns.Add(tc);

                                    //setup the Table RowGroups, we only need 1
                                    tab.RowGroups.Add(new TableRowGroup());

                                    //setup the Table TableCell to hold the image
                                    TableCell tcImageCell = new TableCell();
                                    tcImageCell.ColumnSpan = 1;
                                    tcImageCell.RowSpan = 1;
                                    tcImageCell.TextAlignment = TextAlignment.Left;

                                    //create a border to hold the image for the current detail
                                    Border bord = new Border();
                                    bord.CornerRadius = new CornerRadius(5);
                                    bord.Background = null;
                                    bord.BorderBrush = new SolidColorBrush(Colors.White);
                                    bord.BorderThickness = new Thickness(3);

                                    //create an image for the current detail
                                    Image img = new Image();
                                    img.Stretch = Stretch.Fill;
                                    img.Width = img.Height = 40;

                                    BitmapImage bmpimg = new BitmapImage(new Uri(nonNullprop.PropertyValue));

                                    img.Source = bmpimg;
                                    img.Margin = new Thickness(3);
                                    uiCont = new BlockUIContainer();
                                    uiCont.TextAlignment = TextAlignment.Left;

                                    //add the image to the border and the border to the BlockUIContainer
                                    bord.Child = img;
                                    uiCont.Child = bord;

                                    //add the Image/BlockUIContainer to the previously created TableCell
                                    tcImageCell.Blocks.Add(uiCont);

                                    //setup the Table TableRow to hold the image TableCell
                                    TableRow trImageRow = new TableRow();
                                    trImageRow.Cells.Add(tcImageCell);
                                    tab.RowGroups[0].Rows.Add(trImageRow);

                                    //finally add the Table to the main FlowDocument
                                    flowDoc.Blocks.Add(tab);

                                    doneImage = true;
                                    #endregion
                                }
                            }
                        }
                        else
                        {
                            if (Uri.IsWellFormedUriString(nonNullprop.PropertyValue, UriKind.Absolute))
                            {
                                Paragraph paraValue = new Paragraph();
                                Hyperlink hl = new Hyperlink(new Run("Click Here To View The Link Data"));
                                hl.FontSize = 11;
                                hl.Foreground = new SolidColorBrush(Colors.White);
                                hl.NavigateUri = new Uri(nonNullprop.PropertyValue);
                                hl.Click += new RoutedEventHandler(hl_Click);
                                paraValue.Inlines.Add(hl);
                                flowDoc.Blocks.Add(paraValue);
                            }
                        }
                    }
                    //Not http, so its a normal paragraph
                    else
                    {
                        Paragraph paraValue = new Paragraph();
                        paraValue.FontSize = 10;
                        paraValue.Inlines.Add(new Run(nonNullprop.PropertyValue));
                        flowDoc.Blocks.Add(paraValue);

                    }
                }
            }
            catch { }
        }
        #endregion

        #region Private helpers

        private void CreateParaGraph(SolidColorBrush headerBrsh, AmazonParameterDetail nonNullprop)
        {
            Paragraph paraHeader = new Paragraph();
            paraHeader.FontSize = 12;
            paraHeader.Foreground = headerBrsh;
            paraHeader.FontWeight = FontWeights.Bold;
            paraHeader.Inlines.Add(new Run(nonNullprop.PropertyName));
            flowDoc.Blocks.Add(paraHeader);
        }


        private void hl_Click(object sender, RoutedEventArgs e)
        {
            string url = (e.OriginalSource as Hyperlink).NavigateUri.AbsoluteUri;
            if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
            {
                try
                {
                    Process.Start(new ProcessStartInfo(url));
                }
                catch { }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            (this.Owner as ExplorerWindow).
                favouriteDataItems.Add(new 
                    AmazonFavourite() 
                    {
                        Price = string.IsNullOrEmpty(this.AmazonDetail.OurPrice) ? "" :
                                this.AmazonDetail.OurPrice,

                        AmazonDetail= this.AmazonDetail 
                    }
                );
        }
        #endregion
    }

   
    /// <summary>
    /// Simple data class to hold the results of a LINQ query within the 
    /// <see cref="FlowDocumentWindow">FlowDocumentWindow</see> Window
    /// </summary>
    public class AmazonParameterDetail
    {
        #region Instance Fields
        public string PropertyName { get; set; }
        public string PropertyValue { get; set; }
        #endregion

        #region Ctor
        public AmazonParameterDetail()
        {

        }
        #endregion
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions