【问题标题】:Rendering a UI using IValueConverter using just c# code仅使用 c# 代码使用 IValueConverter 渲染 UI
【发布时间】:2014-06-22 17:30:21
【问题描述】:

我是 c# 和 silverlight-5 初学者。

首先我必须通过反序列化一个 xml 字符串来创建对象。我已经成功地做到了,但现在我的下一步是使用对象元素创建 GUI。我知道我必须使用“IValueConverter”来执行此操作。但我不知道。

包含该对象的我的程序类是这样的:

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

        } 
    }
}

现在的问题是如何从反序列化 (IValueConverter) 获得的对象创建 GUI?

编辑: 我不知道如何实现它:

首先是在包含“IValueConverter”接口的类中,我们必须将(使用 Convert() 函数)对象(在反序列化时获得)转换为参数,然后将这些参数(包含在 c# 中创建的组合框)通过return 到 xaml 代码,其中包含用于呈现我们刚刚使用 c# 创建的 GUI 的容器。

在 Xaml 代码中,我们只需要创建一个容器,该容器将显示我们在上一步中在 c# 代码中创建的组合框和其他标签和文本。 (我们不必在这里使用 xaml 创建组合框,它是在包含返回 UI 的 IValueConverter 接口的类中的 c# 代码中创建的。

例如:(粗略让你理解正确,可能有一些语法错误):

我的“MyValueConverter.cs”类是假设:

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 ://///////////////////
        /////////////////////////////////////////////////
    }
}

而在 xaml 文件中,我必须创建一个容器来呈现在 c#(IValueConverter 接口类)中创建的 UI。 所以我们必须选择任何容器,它必须能够呈现组合框、标签、文本快照的 GUI 中显示的所有数据(容器可以是 StackPanel,因为要显示的东西不止一个).

我的 xaml 代码将包含这样的容器:

<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>

请帮助实现它?如果还不明白,请不要犹豫。

【问题讨论】:

  • 看看隐式数据模板。
  • @HåkanFahlstedt 请您详细解释一下。你知道如何使用 IValueConverter 接口 (converter()) 来实现它吗?
  • IValueConverter 将数据转换为另一种格式,以便 UI 控件显示,而不是提供它自己的 UI。
  • @har07 但我在 c# 代码中有诸如“类型”、“名称”、“标签”、“单位”等元素值,这些值应该是一个 GUI,如“类型”这是组合框。所以它必须提供一个带有项目“5,10,20,50”的组合框 GUI。和“标签”为“最大数量”。这种GUI(见快照)我必须实现。能否请您给我样品以获取想法将是一个很大的帮助。谢谢
  • @user234839 请阅读关于Data BindingData Templates 的介绍性MSDN 文章。

标签: c# silverlight data-binding binding


【解决方案1】:

您可以为此使用隐式数据类型。

在您的 xaml 中,您为特定数据类型定义了一个模板:

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

您最好根据 type-element 值创建不同的类型。另一种解决方案是为 Parameter 类型创建一个大模板,并根据 Parameter-type 包含的内容显示适当的元素。但我不会推荐这种方法。

然后你可以使用 ItemsControl 来显示所有参数:

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

不同的参数会根据它的类型以不同的方式呈现。

【讨论】:

  • 谢谢我的其他课程。我的意思是包含“IValueConverter”接口的类?和其他课程。
  • 我不确定你在问什么,但我的解决方案是替换使用 IValueConverter。
  • 但是你做的方式和 IValuConverter 接口(带有 Convert 和 ConvertBack() 函数)有什么区别呢?
  • 我正在阻碍你的方式,很快就会标记它已解决
  • 以及如何在c#代码后面处理你的xaml代码。
猜你喜欢
  • 2021-10-05
  • 2020-05-05
  • 1970-01-01
  • 2013-04-14
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多