繁体   English   中英

WPF:在ComboBox中使用ItemsControl DataTemplate

[英]WPF: Using the ItemsControl DataTemplate in ComboBox

我正在学习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 在窗口的另一侧,我有一个按钮,用于在包含Candy的ItemsControl中创建新项目。 在这个ItemsControl有一个ComboBox ,我可以指定Candy.Color和一个TextBox ,我指定Candy.Name 最后,当我点击“ 生成列表 ”按钮时,代码应以以下格式在列表下方的TextBox输出:

Candy.Color Candy.Name

彩色糖果机

我试图弄清楚如何自动填充用我创建的颜色列表填充的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>

编辑

我已经删除了所有想法,并使用您的严格设计来实现它: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();
    }
}

如有任何混淆,请通知我,我将尽力提供帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM