Looking for Good XML/Text Scroller

theideabulb
theideabulb used Ask the Experts™
on
I am looking for a scroller that can do the following things, can anyone help me find one.

1. Ability to autoscroll and adjust speed
2. Read content from xml file or text file
3. Ability to format content
4. Still have ability to grab scroll bar to view the content if you want to look for a certain content
5. Abilty to Width, height colors of player
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
Go check out the Tufat site...  He's got multiple variations of the tickers...
   http://www.tufat.com/s_flash_ticker_tape.htm

CyanBlue

Author

Commented:
#3 in your example is close, but I would still like to have a scroll bar in there to move up and down if possible.
There're only few text scrollers on Silverlight, would be much simplier to write one as control by your own.
Could you provide functionality it should have?, so i can create template for you like No.3 from previous post.
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Quite simple solution, just for example.

To edit content appereance just edit DataTemplate. For setting appereance apply few styles.
XAML:

<UserControl x:Class="TextScroller.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="400">
    <UserControl.Resources>
        <DataTemplate x:Name="NewsItemEx">
            <StackPanel Orientation="Vertical" Width="280" Height="200">
                <TextBlock Text="{Binding Title}" FontWeight="Bold" />
                <TextBlock Text="{Binding Content}" TextWrapping="Wrap" />
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot">
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
            <TextBlock Text="Hot News" />
            <ListBox x:Name="Scroller" Width="300" Height="200" MouseEnter="Scroller_MouseEnter" MouseLeave="Scroller_MouseLeave" ItemTemplate="{StaticResource NewsItemEx}" />
        </StackPanel>
    </Grid>
</UserControl>

CS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace TextScroller
{
    public partial class MainPage : UserControl
    {
        System.Windows.Threading.DispatcherTimer scrollDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        public MainPage()
        {
            InitializeComponent();

            scrollDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000); // 100 Milliseconds 
            scrollDispatcherTimer.Tick += new EventHandler(Each_Tick);
            scrollDispatcherTimer.Start();

            List<NewsItem> items = new List<NewsItem>();
            for (int i = 0; i < 23; i++)
            {
                items.Add(new NewsItem() { Title = string.Format("Title {0}", i), Content = "I've seen several questions related to timers on forums and in internal mail so I thought I'd toss up a simple example. To create a timer, you have to use the DispatcherTimer in the System.Windows.Threading namespace." });
            }

            Scroller.ItemsSource = items;
        }

        object selectedItem = null;
        private void ScrollToNext()
        {            
            object nextItemToSelect = null;
            bool getNext = false;
            foreach (object item in Scroller.Items)
            {
                if (selectedItem == null)
                {
                    selectedItem = nextItemToSelect = item;
                    break;
                }
                else if (selectedItem.Equals(item))
                {
                    getNext = true;
                }
                else if (getNext)
                {
                    selectedItem = nextItemToSelect = item;
                    
                    break;
                }
            }

            if (nextItemToSelect != null)
            {
                Scroller.ScrollIntoView(nextItemToSelect);                
            }
            else
            {
                selectedItem = null;
            }

        }

        public void Each_Tick(object o, EventArgs sender)
        {
            ScrollToNext();
        }

        private void Scroller_MouseEnter(object sender, MouseEventArgs e)
        {
            scrollDispatcherTimer.Stop();
        }

        private void Scroller_MouseLeave(object sender, MouseEventArgs e)
        {
            scrollDispatcherTimer.Start();
        }
    }

    public class NewsItem
    {
        public string Title { get; set; }
        public string Content { get; set; }
    }
}

Open in new window

Author

Commented:
I am sorry guys, i don't know the first thing about making something in silverlight or really flash.. I am lookign for somehting that I can buy.. Update the variables and colors and have it work.
Just in case, if won't find any solution, but you'll find someone who can desing this Silverlight App to your site design, here is code that do the following:

1. Read settings from XML (Stored on server)
  -Width
  -Height
  -Ticks (Between items rotation)
  -Item Layout
  -Item data (could be build dynamicly)

Sample of configuration XML:
<?xml version="1.0" encoding="utf-8" ?>
<Scroller>
  <Parameters DispatcherInterval="2000" Width="300" Height="200" />
  <ItemLayout>
    <![CDATA[
            <DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
              <StackPanel Orientation="Vertical" Width="280" Height="200">
                <TextBlock Text="{Binding title}" FontWeight="Bold" />
                <TextBlock Text="{Binding content}" TextWrapping="Wrap" />
              </StackPanel>
            </DataTemplate>
    ]]>
  </ItemLayout>
  <Data>
    <Item title="Content 1" content="Some content 123" />
    <Item title="Content 2" content="Some content 456" />
    <Item title="Content 3" content="Some content 789" />
    <Item title="Content 4" content="Some content 246" />
  </Data>
</Scroller>

* Data element should contain only Item elements with different set of attributes (that would be used to bind your data in ItemLayout)
* ItemLayout is DataTemplate for your scroll item, could be only XAML (so that guy whom you'll find can edit it easily)
* XML file should be placed to site root

Code snippet attached. Unfortunatly EE UI doesnt allow me to attach xap, so this should be builded.

After design and build is done you can place Silverlight on your page, like:

        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
              <param name="source" value="ClientBin/TextScroller.xap"/>
              <param name="onError" value="onSilverlightError" />
              <param name="background" value="white" />
              <param name="minRuntimeVersion" value="3.0.40818.0" />
              <param name="autoUpgrade" value="true" />
              <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
                     <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
              </a>
          </object>

ClientBin/TextScroller.xap should point to your XAP file location.

XAML:
<UserControl x:Class="TextScroller.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="400">
    <Grid x:Name="LayoutRoot">
        <ListBox x:Name="Scroller" Width="300" Height="200" MouseEnter="Scroller_MouseEnter" MouseLeave="Scroller_MouseLeave" />
    </Grid>
</UserControl>

CS:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Xml;
using System.Windows.Markup;
using System.Collections;

namespace TextScroller
{
    public partial class MainPage : UserControl
    {
        System.Windows.Threading.DispatcherTimer scrollDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        List<IDictionary> scrollerItems = new List<IDictionary>();
        
        
        public MainPage()
        {
            InitializeComponent();
            LoadConfiguration();

            scrollDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000); // 100 Milliseconds 
            scrollDispatcherTimer.Tick += new EventHandler(Each_Tick);
            scrollDispatcherTimer.Start();
        }

        private void BindItems()
        {
            if (scrollerItems.Count > 0)
                Scroller.ItemsSource = ((IEnumerable<IDictionary>)scrollerItems).ToDataSource();
        }

        #region Load XML
        private void LoadConfiguration()
        {
            WebClient w = new WebClient();
            w.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadXMLCompleted);
            w.DownloadStringAsync(new Uri("/ScrollerData.xml", UriKind.RelativeOrAbsolute));
        }
        void DownloadXMLCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                string xml = e.Result;

                StringReader stream = new StringReader(e.Result);
                XmlReader reader = XmlReader.Create(stream);
                string imageName = String.Empty;
                string areaName = String.Empty;
                string fileName = String.Empty;

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == "Parameters")
                        {
                            reader.MoveToAttribute("DispatcherInterval");                            
                            if (reader.Value != string.Empty)
                                scrollDispatcherTimer.Interval = new TimeSpan(0,0,0,0,Convert.ToInt32(reader.Value));
                            reader.MoveToAttribute("Width");
                            if (reader.Value != string.Empty)
                                Scroller.Width = Convert.ToDouble(reader.Value);
                            reader.MoveToAttribute("Height");
                            if (reader.Value != string.Empty)
                                Scroller.Height = Convert.ToDouble(reader.Value);
                        }
                        if (reader.Name == "Item")
                        {
                            Dictionary<string, string> dict = new Dictionary<string, string>();

                            reader.MoveToFirstAttribute();
                            for (int i = 0; i < reader.AttributeCount; i++)
                            {
                                dict.Add(reader.Name, reader.Value);
                                reader.MoveToNextAttribute();
                            }

                            scrollerItems.Add(dict);
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.CDATA)
                    {
                        DataTemplate dt = (DataTemplate)XamlReader.Load(reader.Value);
                        Scroller.ItemTemplate = dt;                        
                    }                    
                }

                BindItems();
            }                
        }
        #endregion

        #region Scrolling
        object currentItem = null;
        private void ScrollToNext()
        {
            object nextItemToSelect = null;
            bool getNext = false;
            foreach (object item in Scroller.Items)
            {
                if (currentItem == null)
                {
                    currentItem = nextItemToSelect = item;
                    break;
                }
                else if (currentItem.Equals(item))
                    getNext = true;
                else if (getNext)
                {
                    currentItem = nextItemToSelect = item;
                    break;
                }
            }

            if (nextItemToSelect != null)
            {
                Scroller.ScrollIntoView(nextItemToSelect);
            }
            else
            {
                currentItem = null;
            }

        }
        public void Each_Tick(object o, EventArgs sender)
        {
            ScrollToNext();
        }
        private void Scroller_MouseEnter(object sender, MouseEventArgs e)
        {
            scrollDispatcherTimer.Stop();
        }
        private void Scroller_MouseLeave(object sender, MouseEventArgs e)
        {
            scrollDispatcherTimer.Start();
        }
        #endregion
    }

    public static class DataSourceCreator
    {
        private static readonly Regex PropertNameRegex =
                new Regex(@"^[A-Za-z]+[A-Za-z0-9_]*$", RegexOptions.Singleline);

        private static readonly Dictionary<string, Type> _typeBySigniture =
                new Dictionary<string, Type>();


        public static IEnumerable ToDataSource(this IEnumerable<IDictionary> list)
        {
            IDictionary firstDict = null;
            bool hasData = false;
            foreach (IDictionary currentDict in list)
            {
                hasData = true;
                firstDict = currentDict;
                break;
            }
            if (!hasData)
            {
                return new object[] { };
            }
            if (firstDict == null)
            {
                throw new ArgumentException("IDictionary entry cannot be null");
            }

            string typeSigniture = GetTypeSigniture(firstDict);

            Type objectType = GetTypeByTypeSigniture(typeSigniture);

            if (objectType == null)
            {
                TypeBuilder tb = GetTypeBuilder(typeSigniture);

                ConstructorBuilder constructor =
                            tb.DefineDefaultConstructor(
                                        MethodAttributes.Public |
                                        MethodAttributes.SpecialName |
                                        MethodAttributes.RTSpecialName);


                foreach (DictionaryEntry pair in firstDict)
                {
                    if (PropertNameRegex.IsMatch(Convert.ToString(pair.Key), 0))
                    {
                        CreateProperty(tb,
                                        Convert.ToString(pair.Key),
                                        GetValueType(pair.Value));
                    }
                    else
                    {
                        throw new ArgumentException(
                                    @"Each key of IDictionary must be 
                                alphanumeric and start with character.");
                    }
                }
                objectType = tb.CreateType();

                _typeBySigniture.Add(typeSigniture, objectType);
            }

            return GenerateEnumerable(objectType, list, firstDict);
        }

        private static Type GetTypeByTypeSigniture(string typeSigniture)
        {
            Type type;
            return _typeBySigniture.TryGetValue(typeSigniture, out type) ? type : null;
        }

        private static Type GetValueType(object value)
        {
            return value == null ? typeof(object) : value.GetType();
        }

        private static string GetTypeSigniture(IDictionary firstDict)
        {
            StringBuilder sb = new StringBuilder();
            foreach (DictionaryEntry pair in firstDict)
            {
                sb.AppendFormat("_{0}_{1}", pair.Key, GetValueType(pair.Value));
            }
            return sb.ToString().GetHashCode().ToString().Replace("-", "Minus");
        }

        private static IEnumerable GenerateEnumerable(
                 Type objectType, IEnumerable<IDictionary> list, IDictionary firstDict)
        {
            var listType = typeof(List<>).MakeGenericType(new[] { objectType });
            var listOfCustom = Activator.CreateInstance(listType);

            foreach (var currentDict in list)
            {
                if (currentDict == null)
                {
                    throw new ArgumentException("IDictionary entry cannot be null");
                }
                var row = Activator.CreateInstance(objectType);
                foreach (DictionaryEntry pair in firstDict)
                {
                    if (currentDict.Contains(pair.Key))
                    {
                        PropertyInfo property =
                            objectType.GetProperty(Convert.ToString(pair.Key));
                        property.SetValue(
                            row,
                            Convert.ChangeType(
                                    currentDict[pair.Key],
                                    property.PropertyType,
                                    null),
                            null);
                    }
                }
                listType.GetMethod("Add").Invoke(listOfCustom, new[] { row });
            }
            return listOfCustom as IEnumerable;
        }

        private static TypeBuilder GetTypeBuilder(string typeSigniture)
        {
            AssemblyName an = new AssemblyName("TempAssembly" + typeSigniture);
            AssemblyBuilder assemblyBuilder =
                AppDomain.CurrentDomain.DefineDynamicAssembly(
                    an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");

            TypeBuilder tb = moduleBuilder.DefineType("TempType" + typeSigniture
                                , TypeAttributes.Public |
                                TypeAttributes.Class |
                                TypeAttributes.AutoClass |
                                TypeAttributes.AnsiClass |
                                TypeAttributes.BeforeFieldInit |
                                TypeAttributes.AutoLayout
                                , typeof(object));
            return tb;
        }

        private static void CreateProperty(
                        TypeBuilder tb, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName,
                                                        propertyType,
                                                        FieldAttributes.Private);


            PropertyBuilder propertyBuilder =
                tb.DefineProperty(
                    propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr =
                tb.DefineMethod("get_" + propertyName,
                    MethodAttributes.Public |
                    MethodAttributes.SpecialName |
                    MethodAttributes.HideBySig,
                    propertyType, Type.EmptyTypes);

            ILGenerator getIL = getPropMthdBldr.GetILGenerator();

            getIL.Emit(OpCodes.Ldarg_0);
            getIL.Emit(OpCodes.Ldfld, fieldBuilder);
            getIL.Emit(OpCodes.Ret);

            MethodBuilder setPropMthdBldr =
                tb.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new Type[] { propertyType });

            ILGenerator setIL = setPropMthdBldr.GetILGenerator();

            setIL.Emit(OpCodes.Ldarg_0);
            setIL.Emit(OpCodes.Ldarg_1);
            setIL.Emit(OpCodes.Stfld, fieldBuilder);
            setIL.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }
}

Open in new window

Commented:
Any update???  Please close the topic if you have solve the problem, otherwise explain further on this...

CyanBlue

Commented:
I'd say Silverlay's answer is the most robust one for the Silverlight solution...  ;)

CyanBlue

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial