如何将多个不同的控件绑定到ItemsControl?

时间:2014-02-02 16:06:08

标签: c# .net wpf xaml gridview

我是WPF的新手并且想知道如何在 C#WPF应用程序中将多个不同的控件绑定到 ItemControl ?< / p>

使用我当前的代码,我可以将标签和文本框放入我的ItemControl中。由于我的XAML中的模板定义。

但我喜欢灵活地将标签和其他控件(如组合框,日期选择器等)放入我的ItemControl ...

我怎么能这样做?

我将当前的XAML代码附加了数据模板和代码。这里有一张关于当前外观和我的目标的小图片:

enter image description here

XAML-CODE:

<Window x:Class="WPFFormTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="400">
<Grid>

    <ScrollViewer VerticalScrollBarVisibility="Auto">
        <ItemsControl x:Name="icFields">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="FieldTypes" Margin="10,10,10,10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="75"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Content="{Binding FieldName}" />
                        <TextBox Grid.Column="1" />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>

</Grid>

C#-Code:

    namespace WPFFormTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<Fields> fields = new List<Fields>();
            fields.Add(new Fields() { FieldName = "test1", FieldValue = "1" });
            fields.Add(new Fields() { FieldName = "test2", FieldValue = "2" });
            fields.Add(new Fields() { FieldName = "test3", FieldValue = "3" });

            icFields.ItemsSource = fields;
        }
    }

    public class Fields
    {
        public string FieldName { get; set; }
        public string FieldValue { get; set; }
        public string FieldType { get; set; }
    }
}

3 个答案:

答案 0 :(得分:0)

一种方法可以是:向模板添加所有需要的控件并切换可见性。但是需要视图模型的一些帮助:

<ScrollViewer VerticalScrollBarVisibility="Auto">
        <ScrollViewer.Resources>
            <BooleanToVisibilityConverter x:Key="BoolConverter"/>
        </ScrollViewer.Resources>
        <ItemsControl x:Name="icFields">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="FieldTypes" Margin="10,10,10,10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="75"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Label Content="{Binding FieldName}" />
                        <TextBox Grid.Column="1" Visibility="{Binding ShowText, Converter={StaticResource BoolConverter}}"/>
                        <CheckBox Grid.Column="1" Visibility="{Binding ShowCheckBox, Converter={StaticResource BoolConverter}}" />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>

public class Fields
{
    public string FieldName
    {
        get;
        set;
    }
    public string FieldValue
    {
        get;
        set;
    }

    public bool ShowText
    {
        get;
        set;
    }

    public bool ShowCheckBox
    {
        get;
        set;
    }

    private int fieldType;

    public int FieldType
    {
        get
        {
            return fieldType;
        }

        set
        {
            fieldType = value;
            ShowText = false;
            ShowCheckBox = false;

            switch (fieldType)
            {
                case 0:
                    ShowText = true;
                    break;

                case 1:
                    ShowCheckBox = true;
                    break;
            }
        }
    }
}

答案 1 :(得分:0)

您可能需要考虑使用MVVM框架。我知道Caliburn.Micro有一些内置的功能,可以使用像多态这样的实际OO功能来简化这类工作。

首先,您将为每个项类型定义一个单独的viewmodel类:

public class FieldViewModel { }
public class TextViewModel : FieldViewModel { public string Value {get;set;} }
public class DateViewModel : FieldViewModel { public DateTime Value {get;set;} }

然后,您可以定义一个名为TextView的UserControl,另一个名为DateView。将FieldViewModel列表绑定到UI时,Caliburn.Micro将自动创建正确的视图类型并绑定其属性。

让Caliburn.Micro启动并运行需要一些工作(你需要连接引导程序并创建一个shell视图模型,至少)所以我不会在这里提供完整的代码示例 - 我只是试图告诉你它是否能解决你的问题。对于您需要的实际代码,请按照documentation的方式进行操作;他们很好地指导你完成所有事情。

答案 2 :(得分:0)

最简单的方法是为不同的数据类型提供不同的DataTemplate。例如,如果您有Person课程,则可以使用DataTemplateNameAge Sex字段定义TextBox,而如果您有Car课程,则可以使用DataTemplateMakeModel Year字段定义ComboBox

<DataTemplate DataType="{x:Type DataTypes:Person}">
    <!--Define TextBoxes here-->
</DataTemplate>

<DataTemplate DataType="{x:Type DataTypes:Car}">
    <!--Define ComboBoxes here-->
</DataTemplate>

通过定义这些DataTemplate s 而不指定x:Key引用值,这意味着框架会随时自动应用 它遇到了这些类型的任何实例。因此,这会在Person中显示TextBoxes个详细信息:

<ItemsControl ItemsSource="{Binding Persons}" ... />

这将在Car es:

中显示ComboBox个对象详细信息
<ItemsControl ItemsSource="{Binding Cars}" ... />