1

我正在尝试WrapPanel用我自己的用户控件集合填充 a 。

儿童控制:

<UserControl x:Class="MyApplication.StockMappings.StockView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid Width="140" Height="80">
        <Border CornerRadius="6" BorderBrush="Black" BorderThickness="2" >
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.6*"/>
                    <RowDefinition Height="0.4*"/>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" FontSize="18" FontWeight="Bold">
                    <Label Content="{Binding Path=ID}"/>
                </TextBlock>
                <TextBlock Grid.Row="1" FontSize="12" FontWeight="Bold">
                    <Label Content="{Binding Path=StockName}"/>
                </TextBlock>
            </Grid>
        </Border>
    </Grid>
</UserControl>

cs 文件:

namespace MyApplication.StockMappings
{
    /// <summary>
    /// Interaction logic for StockView.xaml
    /// </summary>
    public partial class StockView : UserControl
    {
        public StockView()
        {
            InitializeComponent();
        }

        public string ID
        {
            get;
            set;
        }

        public string StockName
        {
            get;
            set;
        }
    }
}

最后,带有环绕面板的窗口:

<Window x:Class="MyApplication.StockMappings.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyApplication.StockMappings"
        Title="TestWindow" Height="300" Width="300">
    <Grid>
        <ItemsControl Name="Stocks" ItemsSource="{Binding AllStocks}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"/>                        
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:StockView/>                                            
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

又是 C# 代码:

public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();
        var stocks = new[]
        {
            new StockView() { ID = "M0", StockName = "abc"},
            new StockView() { ID = "M1", StockName = "def"},
        };

        Stocks.DataContext = new Test()
        {
            AllStocks = stocks.ToList()
        }; 
    }
}

类(子数据的Test容器)非常简单:

public class Test
{
    public List<StockView> AllStocks
    {
        get;
        set;
    }
}

最后,结果:

截屏

所有边框都是空白的。既不ID也不StockName显示。

我究竟做错了什么?

我已经确认(通过添加一个虚拟属性)StockView控件ID从对象中获取值Test,而不是从AllStocks列表中获取子项。但为什么?我没有定义ItemTemplate吗?那它是为了什么?

4

4 回答 4

2

您缺少的是保存数据的适当视图模型项类。这不应与视图对象混淆,例如您的 StockView。

首先,从 StockView 控件中删除ID和属性。StockName这些属性将移至数据项类。

public partial class StockView : UserControl
{
    public StockView()
    {
        InitializeComponent();
    }
}

其次,使用StockItem数据项类和ViewModel具有该属性的类创建视图模型(或者像您已经做过的那样AllStocks调用它)。Test

public class StockItem
{
    public string ID { get; set; }
    public string StockName { get; set; }
}

public class ViewModel
{
    public ObservableCollection<StockItem> AllStocks { get; set; }
}

最后,将 MainWindow 的 DataContext 设置为 ViewModel 类的实例。

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel { AllStocks = new ObservableCollection<StockItem>() };
    vm.AllStocks.Add(new StockItem { ID = "M0", StockName = "abc" });
    vm.AllStocks.Add(new StockItem { ID = "M1", StockName = "def" });

    DataContext = vm;
}

AllStocks如果数据项在添加到集合后可以修改,则StockItem该类必须实现该INotifyPropertyChanged接口。

于 2013-04-29T15:25:33.367 回答
1

那么,用户控件DataContextStockView应该是它自己的代码背后的类。

那应该使它起作用!

public StockView()
{
    InitializeComponent();
    this.DataContext = this;
}
于 2013-04-29T14:56:13.000 回答
1

例如在代码中设置用户控件的数据内容:

public StockView()
        {
            InitializeComponent();
            DataContext = this;
        }
于 2013-04-29T14:56:55.717 回答
1

DataTemplates模板数据,您绑定到控件列表,ItemTemplate将被忽略,因为可以直接添加控件,您应该在输出中收到关于此的警告。由于DataContext为 设置了这个 no UserControls,您应该将属性从 移动UserControl到模型类并添加它的实例。另外我建议不要设置DataContext你的UserControl.

于 2013-04-29T15:22:18.900 回答