WPF Usercontrol项目未显示

时间:2012-11-15 17:42:13

标签: c# wpf binding

我有一个用wpf构建的条形图。用户指定栏内的项目。

BarChart.xaml.cs

public partial class BarChart : UserControl
{
    List<BarItem> BarItems = new List<BarItem>();
    List<Bar> Bars = new List<Bar>();
    public List<BarItem> Items
    {
        get { return BarItems; }
        set
        {
            BarItems = value;
            Bars.Clear();
            int i=0;
            this.LayoutRoot.Children.Clear();
            //This line should show up but doesn't suggesting that that the property is not being set?
            Debug.WriteLine("SET");
            foreach(BarItem Item in BarItems){
                Bar ThisBar=new Bar();
                ThisBar.CurrentLable=Item.Lable;
                ThisBar.CurrentValue=Item.Value;
                Debug.WriteLine("{0}:{1} at {2}",Item.Lable,Item.Value,(i*55));
                ThisBar.CurrentX=i*55;
                this.AddChild(ThisBar);
                i++;
            }
            Debug.WriteLine(i);
        }
    }
    public BarChart()
    {
        this.InitializeComponent();
    }
}

BarChart.xaml

<UserControl
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:CipherCracker"
mc:Ignorable="d"
x:Class="CipherCracker.BarChart"
x:Name="BarChartList"
d:DesignWidth="640" d:DesignHeight="480">

<Grid x:Name="LayoutRoot"/>
</UserControl>

BarItem.cs

public class BarItem
{
    public int Value
    {
        get;
        set;
    }
    public string Lable
    {
        get;
        set;
    }
    public BarItem()
    {

    }

}

要添加新的BarChart,请运行

<local:BarChart>
    <local:BarChart.Items>
        <local:BarItem Lable="B" Value="75"/>
        <local:BarItem Lable="A" Value="50"/>
    </local:BarChart.Items>
</local:BarChart>

然而根据输出,没有添加任何项目。我做错了什么,有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

你的问题是属性设置器实际上从未被调用过。

按照您在XAML中的方式添加BarItem对象,将项目添加到现有列表实例。只有在将列表设置为新实例时才会调用属性设置器。

所以我会在代码隐藏中创建一个新列表,并在那里设置属性。这样做会调用setter,你的代码就会运行。您可能需要为BarChart命名,以便您可以参考它。

<强> XAML

<local:BarChart x:Name="bar">
    <!-- Doing this adds BarItems to the existing list. 
    <local:BarChart.Items>
        <local:BarItem Lable="B" Value="75"/>
        <local:BarItem Lable="A" Value="50"/>
    </local:BarChart.Items>
    -->
</local:BarChart>

<强>代码隐藏

public MainWindow()
{
    InitializeComponent();

    //Setting the Items property to a new list, will call the setter..
    bar.Items = new List<BarItem>
    {
        new BarItem { Lable = "Test1", Value = 500 }, 
        new BarItem { Lable = "Test2", Value = 1000 },
        new BarItem { Lable = "Test3", Value = 1500 }
    };
}

答案 1 :(得分:2)

此外,我认为您可以使用ObservableCollection<BarItem>执行此操作,然后注册到事件CollectionChanged以控制插入和删除。

但我认为正确的方法是使用DependencyProperty ICollection,然后如果集合实现ICollectionChanged接口,您可以控制插入和删除以更新如果您想要对此集合进行绑定,这应该非常有用。

希望这对你有帮助,......

答案 2 :(得分:1)

我会用Binding做到这一点。代码隐藏只是持有一个属性:

public partial class BarChart : UserControl
{
    private List<BarItem> _items;
    public List<BarItem> Items
    {
        get { return _items ?? (_items = new List<BarItem>()); }
        set { _items = value; }
    }

    public BarChart()
    {
        InitializeComponent();
    }
}

虽然UI会做其余的事情:

<ItemsControl ItemsSource="{Binding Items, ElementName=BarChartList}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:Bar CurrentLable={Binding Lable} CurrentValue={Binding Value}/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

用户界面中发生了哪些变化:

    ItemsControl不同,
  • Grid具有有用的ItemsSource属性,这使事情变得更容易;
  • StackPanel不同,
  • Grid无需通过堆叠项目手动定位项目。如果您希望项目之间存在差距,可以将local:Bar Margin设置为常量值。