1

私はWPFを初めて使用するので、私の質問がばかげている場合はお詫び申し上げます。

「フード メニュー」と「オーダー リスト」の 2 つの主要なセクションで構成される食品注文システムを作成しています。ユーザーが食品メニューからアイテムを選択すると、注文リストを表すリストボックス コントロールに追加されます。

「OrderLine」のコレクション クラス と同様に、Orderいくつかのカスタム オブジェクトを作成しました。それらは次のようになります。 OrderLineItemOrderLineCollection

public class Order
{
    public string ID { get; set; }
    public DateTime DateTime { get; set; }
    public double TotalAmt { get; set; }
    public OrderLineCollection LineItems { get; set; }
}

public class OrderLine
{
    public Item Item { get; set; }
    public double UnitPrice { get; set; }
    public int Quantity { get; set; }
    public double SubTotal { get { return unitPrice * quantity; } }
}

[Serializable]
public class OrderLineCollection : CollectionBase
{
    public OrderLine this[int index]
    {
        get { return (OrderLine)List[index]; }
        set { List[index] = value; }
    }
}

public class Item
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public double UnitPrice { get; set; }
    public byte[] Image { get; set; }
}

私のListBoxコントロールには、DataTemplate各項目の詳細が表示されるようにするための があります。XAML は次のとおりです。

<Page x:Class="FoodOrdering.OrderList"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Order List">
    <ListBox Name="lbxOrder" HorizontalContentAlignment="Stretch">            
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition Width="80"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition Height="40"/>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Text="{Binding item.name}"/>
                    <TextBlock Grid.Row="0" Grid.Column="1" Text="x "/>
                    <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding quantity}" Margin="10,0,0,0"/>
                    <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding subTotal, Converter={StaticResource priceConverter}}" HorizontalAlignment="Right"/>
                    <Button Grid.Row="1" Grid.Column="2" Margin="0,5,0,0" Click="btnDelete_Click">Delete</Button>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Page>

そのため、アイテムが追加されると、ListBox は次の画像のようになります: https://dl.dropbox.com/u/6322828/orderList.png

コード ビハインドではcurrentOrder、現在の注文を格納するための静的変数を作成しました。これは他のクラス/メソッドで使用されます。

そして、その値が変更されるたびに、次のばかげたメソッドLoadCurrentOrder()が呼び出されて ListBox ビューが更新されます。

public partial class OrderList : Page
{
    public static Order currentOrder = new Order();
    public OrderList()
    {
        InitializeComponent();
        LoadCurrentOrder();
    }

    public void LoadCurrentOrder()
    {
        lbxOrder.Items.Clear();
        foreach (OrderLine ol in currentOrder.LineItems)
            lbxOrder.Items.Add(ol);
    }
}

Resources ItemsSource私の問題は、変数の値が変更されるたびに ListBox が自動的に更新されるように、上記の方法を使用する代わりに、エレガントな方法 (を使用するなど) でデータをバインドするにはどうすればよいですか?

私は試した

lbxOrder.ItemsSource = currentOrder; 

currentOrder はオブジェクトではないため、機能しませんSystem.Collections.IEnumerable

4

2 に答える 2

4

1 - 独自のコレクション型を作成しないでください。.Net フレームワークの基本クラス ライブラリには、必要なものがほとんどすべて含まれています。

を取り外してOrderLineCollection使用しObservableCollection<OrderLine>ます。

2 - MVVM の規則に従うようにしてください。これは、コードで UI 要素を操作してはならないことを意味します。

public OrderList()
{
    InitializeComponent();
    LoadCurrentOrder();
    DataContext = this;
}

次に XAML で:

<ListBox ItemsSource="{Binding LineItems}" HorizontalContentAlignment="Stretch">

3 - XAML で参照する必要がない限り、XAML で UI 要素に名前を付けないでください。これは、手続き型コードで UI 要素を操作したいと思うたびに、アプローチを再考するのに役立ちます。

4 - C# の命名規則に慣れる。プロパティ名は「適切なケース」にする必要があります (LineItemsの代わりにIE lineItems)

于 2013-03-05T16:23:29.357 に答える
0

あなたがしなければならないのは、lineItemsプロパティをにすることObservableCollection<yourType>です。次に、このコレクションが変更されると(アイテムが追加、削除されると)、リストボックスが自動的に更新されます。

問題が順序自体が変更され、リストボックスを更新する必要がある場合。次に、実装するだけでINotifyPropertyChanged、順序が変更されたときに、プロパティが変更されたという通知がトリガーされ、UIがバインディングを介して更新されます。

よりエレガントな方法でのバインディングに関しては。あなたはにバインドすることができますcurrentOrder.lineItems

lbxOrder.ItemsSource = currentOrder.lineItems;//this should be an observable collection if you intend to have items change
于 2013-03-05T16:17:39.103 に答える