1

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()
    {

    }

}

実行する新しい棒グラフを追加するには

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

しかし、出力によると、アイテムは追加されていません。私は何を間違っているのですか、そしてより良い方法はありますか?

4

3 に答える 3

2

あなたの問題は、プロパティセッターが実際に呼び出されることは決してないということです。

XAMLで行っている方法でBarItemオブジェクトを追加すると、既存のリストインスタンスにアイテムが追加されます。プロパティセッターは、リストを新しいインスタンスに設定したときにのみ呼び出されます。

そこで、コードビハインドで新しいリストを作成し、そこにプロパティを設定します。これを行うとセッターが呼び出され、コードが実行されます。参照できるように、棒グラフに名前を付ける必要がある場合があります。

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 }
    };
}
于 2012-11-15T18:28:12.470 に答える
2

また、を使用してこれを実行し、挿入と削除を制御するためObservableCollection<BarItem>のイベントに登録できると思います。CollectionChanged

DependencyPropertyしかし、これを行う正しい方法は、のを使用することだと思います。ICollectionコレクションがインターフェイスを実装している場合はICollectionChanged、ビューを更新するための挿入と削除を制御できます。これは、このコレクションにバインドを作成する場合に非常に便利です。

これがあなたに役立つことを願っています...

于 2012-11-15T19:08:11.897 に答える
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>

UIで変更された点:

  • ItemsControlとは異なりGrid、便利なItemsSourceプロパティがあり、作業が簡単になります。
  • StackPanelとは異なりGrid、アイテムを積み重ねて手動で配置する必要がありません。local:Bar Marginアイテム間にギャップを持たせたい場合は、一定の値に設定できます。
于 2012-11-15T19:00:23.740 に答える