2012-11-15 158 views
1

我有一个内置wpf的条形图。用户指定栏内的项目。WPF Usercontrol Items not showing

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> 

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

+0

你是如何将BarItems添加到BarChart的? – Joulukuusi

+0

BarChart.xaml.cs中有一个名为Items的属性。此set属性循环了各项并将它们添加到LayoutRoot – Bonzo

+0

@Rachel有答案,您说在调试窗口中存在“SET 0”。这意味着你正在设置'Items'错误。你可以向BarChart发布添加项目的最小样本吗? – Joulukuusi

回答

1

我会做到这一点用结合。代码隐藏将只是抱着一个属性:

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> 

什么已经在UI被改变:

  • ItemsControl,不像Grid ,有用ItemsSource属性,这使事情变得更容易;
  • StackPanel,与Grid不同,它不需要通过堆叠手动定位项目。如果您想在项目之间有空隙,您可以将local:Bar Margin设置为一个常数值。
2

你的问题是属性setter从来没有被调用。

以您在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 } 
    }; 
} 
2

另外我认为你可以使用ObservableCollection<BarItem>来做到这一点,然后注册到事件CollectionChanged来控制插入和删除。

但我认为这样做的正确的方式,如果集合实现ICollectionChanged接口,你可以控制插入和删除用于更新view.This应该是非常有用的,如果你可能需要使用ICollectionDependencyProperty,然后绑定到这个集合。

希望这可以帮助你,...