【问题标题】:WPF: Using the ItemsControl DataTemplate in ComboBoxWPF:在 ComboBox 中使用 ItemsControl DataTemplate
【发布时间】:2015-09-19 11:31:53
【问题描述】:

我正在学习 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。最后,当我点击按钮 Generate List 时,代码应该在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>

【问题讨论】:

    标签: c# wpf combobox itemscontrol


    【解决方案1】:

    编辑

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

    如果有任何困惑,请告诉我,我会尽力提供帮助

    【讨论】:

    • 嗨@sandesh,我注意到你所做的改变并不是我想要的。我希望当我点击“New Candy”时,我可以在窗口右上角的 ItemsControl 中创建一个新项目,这样我就可以看到每种颜色的每个糖果。
    • 您好,我无法测试新的,但我能够自己解决。该解决方案类似于您提出的解决方案。谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2012-07-30
    • 2021-05-18
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2015-11-08
    相关资源
    最近更新 更多