具有子类的WPF数据绑定

时间:2019-03-20 15:56:51

标签: c# wpf

我试图加入WPF,因此我试图为自己做一个好榜样。经过几次尝试,我开始对WFP中的数据绑定如何工作感到有些困惑。

这是我的示例:

让我们说我的项目有3个班级:

  • 产品
  • 类别
  • 标签

为此,我在这里获得了这些课程:

类别:

public class Category
{
    private int id;
    private string name;

    public int Id { get => id; set => id = value; }
    public string Name { get => name; set => name = value; }
}

标签:

public class Tag
{
    private int id;
    private string name;

    public int Id { get => id; set => id = value; }
    public string Name { get => name; set => name = value; }
}

产品:

public class Product
{
    private int id;
    private string name;
    private double price;
    private int categoryID;
    private ICollection<Tag> tags;

    public int Id { get => id; set => id = value; }
    public string Name { get => name; set => name = value; }
    public double Price { get => price; set => price = value; }
    public int CategoryID { get => categoryID; set => categoryID = value; }
    public ICollection<Tag> Tags { get => tags; set => tags = value; }

    public Category Category
    {
        get => default(Category);
        set{}
    }
}

让我们说我从某处获取数据来填充这些类:

List<Product> products = new List<Product>();

products.Add(new Product() { Id = 1, Name = "Toy Car", Price = 14.99, 
CategoryID = 2, Tags = new List<Tag>() { new Tag { Id = 1, Name = "Toy" }, 
new Tag { Id = 2, Name = "Kids" } } });

products.Add(new Product() { Id = 1, Name = "Water", Price = 14.99, 
CategoryID = 2, Tags = new List<Tag>() { new Tag { Id = 3, Name = "Food" } } 
});

List<Category> categories = new List<Category>();
categories.Add(new Category() { Id = 1, Name = "Food" });
categories.Add(new Category() { Id = 2, Name = "Toys" });

我的用户界面如下:

UI

MainWindow.xaml:

<Window
    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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:wfp_test"x:Class="wfp_test.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.Resources>
    <CollectionViewSource x:Key="productViewSource" d:DesignSource="{d:DesignInstance {x:Type local:Product}, CreateList=True}"/>
    <CollectionViewSource x:Key="productTagsViewSource" Source="{Binding Tags, Source={StaticResource productViewSource}}"/>
</Window.Resources>
<Grid DataContext="{StaticResource productTagsViewSource}" >
    <Grid x:Name="grid1" DataContext="{StaticResource productViewSource}" HorizontalAlignment="Left" Margin="13,154,0,0" VerticalAlignment="Top">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Label Content="Category:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
        <ComboBox x:Name="categoryComboBox" Grid.Column="1" DisplayMemberPath="Category" HorizontalAlignment="Left" Height="Auto" ItemsSource="{Binding}" Margin="3" Grid.Row="0" VerticalAlignment="Center" Width="120">
            <ComboBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </ComboBox.ItemsPanel>
        </ComboBox>
        <Label Content="Id:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="2" VerticalAlignment="Center"/>
        <TextBox x:Name="idTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="2" Text="{Binding Id, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
        <Label Content="Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="3" VerticalAlignment="Center"/>
        <TextBox x:Name="nameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="3" Text="{Binding Name, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
        <Label Content="Price:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="4" VerticalAlignment="Center"/>
        <TextBox x:Name="priceTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="4" Text="{Binding Price, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
    </Grid>
    <DataGrid x:Name="tagsDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Margin="382,155,10,64" RowDetailsVisibilityMode="VisibleWhenSelected">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="idColumn" Binding="{Binding Id}" Header="Id" Width="SizeToHeader"/>
            <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}" Header="Name" Width="SizeToHeader"/>
        </DataGrid.Columns>
    </DataGrid>
    <ListView x:Name="productListView" ItemsSource="{Binding Source={StaticResource productViewSource}}" Margin="10,10,10,296" SelectionMode="Single">
        <ListView.ItemContainerStyle>
            <Style>
                <Setter Property="Control.HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="Control.VerticalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.View>
            <GridView>
                <GridViewColumn x:Name="categoryColumn" Header="Category" Width="80">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox Margin="6,-1,-6,-1">
                                <ComboBoxItem Content="{Binding Category}"/>
                            </ComboBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn x:Name="categoryIDColumn" Header="Category ID" Width="80">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Margin="-6,-1" Text="{Binding CategoryID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn x:Name="idColumn1" Header="Id" Width="80">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Margin="-6,-1" Text="{Binding Id, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn x:Name="nameColumn1" Header="Name" Width="80">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Margin="-6,-1" Text="{Binding Name, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn x:Name="priceColumn" Header="Price" Width="80">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Margin="-6,-1" Text="{Binding Price, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        List<Product> products = new List<Product>();
        products.Add(new Product() { Id = 1, Name = "Toy Car", Price = 14.99, CategoryID = 2, Tags = new List<Tag>() { new Tag { Id = 1, Name = "Toy" }, new Tag { Id = 2, Name = "Kids" } } });
        products.Add(new Product() { Id = 1, Name = "Water", Price = 14.99, CategoryID = 1, Tags = new List<Tag>() { new Tag { Id = 3, Name = "Food" } } });

        List<Category> categories = new List<Category>();
        categories.Add(new Category() { Id = 1, Name = "Food" });
        categories.Add(new Category() { Id = 2, Name = "Toys" });

        System.Windows.Data.CollectionViewSource productViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("productViewSource")));
        categoryComboBox.ItemsSource = categories;
        productViewSource.Source = products;
    }
}

我的第一个问题 categoryComboBox 始终为空。我的第二个问题是如何设置此框的 ValueMember DisplayMember ,以及在哪里可以用类别中的数据填充? >

1 个答案:

答案 0 :(得分:0)

DisplayMemberPath应该设置为“名称”。您也可以将SelectedValuePath设置为“ Id”:

<ComboBox x:Name="categoryComboBox" DisplayMemberPath="Name" SelectedValuePath="Id" ... />