WPF:在ComboBox中使用ItemsControl DataTemplate

时间:2015-09-17 13:33:39

标签: c# wpf combobox itemscontrol

我正在学习WPF,我正在尝试做一些简单的事情。我有两个班级:CandyMyColor。这两个类的代码看起来像这样

public class Candy
{
    public MyColor Color { get; set; }
    public string Name { get; set; }
}

public class MyColor
{
    public string Name { get; set; }
    public uint Id { get; set; }
}

(我已在下方附上图片以使其更清晰)

我在窗口中有一个区域,我可以使用插入MyColor的文本框和MyColor.Name递增的简单逻辑创建MyColor.Id。在窗口的另一侧,我有一个按钮,在ItemsControl中创建新项目,其中包含Candy。在此ItemsControl中,我可以指定ComboBox Candy.ColorTextBox,我指定Candy.Name。最后,当我点击按钮生成列表时,代码应该以

的格式输出到列表下方的TextBox

Candy.Color Candy.Name

Color Candy Maker

我正在试图弄清楚如何自动填充填充了我创建的颜色列表的ComboBox,这样我可以指定Candy颜色,但我不知道如何绑定我的数据来源。另外,我如何生成文本?

目前我的代码看起来像这样

namespace QuestionToAsk
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    ObservableCollection<MyColor> Colors;
    ObservableCollection<Candy> Candies;

    public MainWindow()
    {
        InitializeComponent();
        Colors = new ObservableCollection<MyColor>();
        Candies = new ObservableCollection<Candy>();

        Colors.Add(new MyColor() { Name = "(Unspecified)", Id = 0 });

        icColors.ItemsSource = Colors;
        icCandies.ItemsSource = Candies;
    }

    private void btnColor(object sender, RoutedEventArgs e)
    {
        if (txtColor.Text != "")
        {
            uint last_id = Colors.Last<MyColor>().Id;
            Colors.Add(new MyColor() { Name = txtColor.Text, Id = last_id+1 });
            txtColor.Text = "";
        }
    }

    private void btnNewCandy(object sender, RoutedEventArgs e)
    {
        Candies.Add(new Candy());
    }

    private void btnGetList(object sender, RoutedEventArgs e)
    {
        //How to create the list of <Color, Name>?
    }
}

public class Candy
{
    public MyColor Color { get; set; }
    public string Name { get; set; }
}

public class MyColor
{
    public string Name { get; set; }
    public uint Id { get; set; }
}
}

我的XML文件如下所示:

<Window x:Class="QuestionToAsk.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:QuestionToAsk"
        Title="Color Candy Maker" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <DockPanel Margin="3">
            <Button Content="Add Color" Click="btnColor" DockPanel.Dock="Bottom"/>
            <TextBox x:Name="txtColor" DockPanel.Dock="Bottom"/>
            <ItemsControl x:Name="icColors" Grid.Column="0" Grid.Row="0" DockPanel.Dock="Top">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:Name="tColorsTemplate">
                        <TextBlock Text="{Binding Name}" Name="Color" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DockPanel>
        <DockPanel Grid.Column="1" Grid.Row="0" Margin="3">
            <Grid DockPanel.Dock="Bottom">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button Content="New Candy" Click="btnNewCandy" Grid.Column="0"/>
                <Button Content="Generate List" Click="btnGetList" Grid.Column="1"/>
            </Grid>
            <ItemsControl Name="icCandies" DockPanel.Dock="Top">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <ComboBox Name="cmbColors" Grid.Column="0">
                               <!-- How to bind this cmbColors to icColors? -->
                            </ComboBox>
                            <TextBox Text="{Binding Name}" Grid.Column="1" />
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DockPanel>
        <DockPanel  Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
            <TextBox x:Name="txtColorCandy"/>
        </DockPanel>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:0)

修改

我删除了所有想法并使用您的硬设计实现了它:D。

xaml代码

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <DockPanel Margin="3">
        <Button Content="Add Color" Click="btnColor" DockPanel.Dock="Bottom"/>
        <TextBox x:Name="txtColor" DockPanel.Dock="Bottom"/>
        <ItemsControl x:Name="icColors" Grid.Column="0" Grid.Row="0" DockPanel.Dock="Top">
            <ItemsControl.ItemTemplate>
                <DataTemplate x:Name="tColorsTemplate">
                    <TextBlock Text="{Binding Name}" Name="Color" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>
    <DockPanel Grid.Column="1" Grid.Row="0" Margin="3">
        <Grid DockPanel.Dock="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Button Content="New Candy" Click="btnNewCandy" Grid.Column="0"/>
            <Button Content="Generate List" Click="btnGetList" Grid.Column="1"/>
        </Grid>
        <ItemsControl Name="icCandies" DockPanel.Dock="Top">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <ComboBox Name="cmbColors" Grid.Column="0"
                                  ItemsSource="{Binding Colors, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                  DisplayMemberPath="Name"
                                  SelectedItem="{Binding Color}">
                        </ComboBox>
                        <TextBox Text="{Binding Name}" Grid.Column="1" />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>
    <DockPanel  Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
        <TextBox x:Name="txtColorCandy" VerticalScrollBarVisibility="Auto"/>
    </DockPanel>
</Grid>

请注意RelativeSource的使用情况,因为ComboBox的值属于Window类的属性,而选定的值将保存在Candy类中。因此ItemsSource绑定到Window类的属性,SelectedItem绑定到Candy类的属性

背后的代码

public partial class MainWindow : Window
{
    private ObservableCollection<MyColor> _colors;

    public IEnumerable<MyColor> Colors
    {
        get { return _colors; }
    }

    private ObservableCollection<Candy> _candies;

    public IEnumerable<Candy> Candies
    {
        get { return _candies; }
    }

    public MainWindow()
    {
        InitializeComponent();
        _colors = new ObservableCollection<MyColor>();
        _candies = new ObservableCollection<Candy>();

        _colors.Add(new MyColor { Name = "(Unspecified)", Id = 0 });
        icColors.ItemsSource = Colors;
        icCandies.ItemsSource = Candies;
    }

    private void btnColor(object sender, RoutedEventArgs e)
    {
        if (txtColor.Text != "")
        {
            uint last_id = Colors.Last<MyColor>().Id;
            _colors.Add(new MyColor() { Name = txtColor.Text, Id = last_id + 1 });
            txtColor.Text = "";
        }
    }

    private void btnNewCandy(object sender, RoutedEventArgs e)
    {
        _candies.Add(new Candy());
    }

    private void btnGetList(object sender, RoutedEventArgs e)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var item in _candies)
        {
            if (item.Name == null || item.Color == null)
                continue;
            sb.AppendLine(item.Color.Name + " " + item.Name);
        }

        txtColorCandy.Text = sb.ToString();
    }
}

有任何混淆让我知道,我会尽力帮助