Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

silverlight - Rendering a UI using IValueConverter using just c# code

I am c# and silverlight-5 beginner.

First i had to create object by deserializing an xml string. I have done that succesfully but now my next step is to create GUI using the object elements. I have idea that i have to use "IValueConverter" for doing this. But how that i dont know.

My Program class which contains the object is like this:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Runtime.Serialization.Json;
using System.Runtime;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml;
using System.Collections;
namespace Model.XML
{
    public class ProgramControl
    {
        public static void Main()
        {
            string xmlstring = @"<?xml version='1.0' encoding='utf-8' ?> 
                       <parameter>  
                       <name>max_amount</name>
                       <label>Max Amount</label>
                       <unit>Millions</unit>
                       <component>
                       <type>Combo</type>
                       <attributes>
                       <type>Integer</type>
                       <displayed>4</displayed>
                       <selected>0</selected>
                       <items>
                       <item>5</item>
                       <item>10</item>
                       <item>20</item>
                       <item>50</item>
                       </items>
                       </attributes>
                       </component >
                       </parameter>";    

            XmlSerializer deserializer = new XmlSerializer(typeof(Parameter));
            XmlReader reader = XmlReader.Create(new StringReader(xmlstring));

            Parameter parameter = (Parameter)deserializer.Deserialize(reader);


            foreach (var item in parameter.Component.Attributes.Items)
            {
                Debug.WriteLine(item);
            }    

            Debug.WriteLine(parameter.Component.Type);
            Debug.WriteLine(parameter.Name);
            Debug.WriteLine(parameter.Label);
            Debug.WriteLine(parameter.Unit);

        } 
    }
}

Now the question is how can i create GUI from the object obtained on deserializing (IValueConverter )?

EDIT: I have little idea of how it can be achieved:

First thing is in the class containing "IValueConverter" interface we have to convert(using Convert() function) the objects(obtained on deserializing) in to parameters and then pass those parameteres (containing combo box created in c# here) through return to the xaml codewhich contains the container to render the GUI we just created using c#.

And in Xaml code we just need to create container which will display the combo box and other labels and text we created in c# code in previous step. (We don't have to create combo box using xaml here, it is created in c# code inside the class containing IValueConverter interface which returns the UI).

For example: (It's rough idea to make you understand properly, there may be some syntatical error):

My "MyValueConverter.cs" class is suppose:

public class MyValueConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture) 
    {

        List<parameter> list = value as List<Parameter>;
        List<UIElement> result = new List<UIElement>();

        foreach(parameter p in list)
        {
            UIElement newEle = null;
            if (p.component.type == "Combo")
            {
                newEle = new ComboBox();

            }
            result.add(newEle);
        }
        return result;
        /////////////////////////////////////////////////
        //////////////// and so on ://///////////////////
        /////////////////////////////////////////////////
    }
}

Whereas in xaml file i have to create a container that will render the UI created in c#(IValueConverter interface class). So we have to chose any container which must be capable of rendering the combo box , label, text all the datas shown in GUI of snapshot (conatiner could be StackPanel because there are more than one thing to be displayed).

my xaml code will be just containign a container like this:

<UserControl x:Class="RenderingTest.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:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:this="clr-namespace:RenderingTest.Converters"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <this:MyValueConverter x:Key="ImageConverter"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" Width="Auto" Height="Auto">
        <!-- There should be container here to render the combo box
             created using c# code in "MyValueConverter" class -->
    </Grid>
</UserControl>

Any help in achieveing it please ? Please do not hesitate to ask if couldn't understand yet.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use Implicit Data Types for this.

In your xaml you define a template for a certain datatype:

<DataTemplate DataType="ComboParameter">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text={Binding Path=label}" />
            <ComboBox ItemsSource="{Binding Path=items}"/>
            <TextBlock Text="{Binding Path=unit}"/>
        </StackPanel>
</DataTemplate>

You better create different types depending on the type-element value. Another solution is to create a large template for the type Parameter, and show the appropriate elements depending on what the Parameter-type contains. But I wouldn't recommend this approach.

Then you can use an ItemsControl to display all parameters:

<ItemsControl ItemsSource="{Binding Path=Parameters}" />

The different parameters will be rendered in different ways depending on what type it has.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...