XAML Win8 Databinding TwoWay带有Observable Collection

时间:2014-05-30 13:27:43

标签: c# xaml windows-store-apps

我对Win8 App开发和XAML相对较新(这是我的第一个正确的堆栈溢出帖子,所以请轻轻地对我!)。

通过我的项目,我创建了一个订单页面,显示订单标题详细信息,然后是订单行列表。 在订单行上,我需要用户能够更新数量(这是我正在努力解决的问题)。

我创建了以下类:

 
public class OrderDetails 
{

    public class OrderDetailsLine : INotifyPropertyChanged
    {
        public string ItemNo { get; set; }
        public string ItemDescription { get; set; }

        private decimal quantity;
        public decimal Quantity 
        { 
            get
            {
                return quantity;
            }

            set
            {
                quantity = value;
                OnPropertyChanged();
            }
        }


        public decimal Price { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string caller = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                   new PropertyChangedEventArgs(caller));
            }
        }
    }

    public class OrderDetailsHeader : INotifyPropertyChanged
    {
        public string OrderNo { get; set; }
        public string CustNo { get; set; }
        public string CustName { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string County { get; set; }
        public string PostCode { get; set; }

        private string _externalDocNo;
        public string ExternalDocNo 
        { 
            get
            {
                return _externalDocNo;
            }
            set
            {
                _externalDocNo = value;
                OnPropertyChanged();
            }
        }

        public DateTime PostingDate { get; set; }

        private ObservableCollection<OrderDetailsLine> _Lines = new ObservableCollection<OrderDetailsLine>();
        public ObservableCollection<OrderDetailsLine> Lines
        {
            get
            {
                return this._Lines;
            }

            set
            {
                _Lines = value;
                OnPropertyChanged();
            }

        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string caller = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                   new PropertyChangedEventArgs(caller));

            }
        }
    }

在我的XAML代码中,我有一个TextBox,它使用对OrderDetails.OrderDetailHeader.ExternalDocNo的双向数据绑定。

但是我也有一个带有DataTemplate的ListView,其中TextBox绑定到OrderDetails.OrderDetailHeader.Lines.Quantity

 
<ListView 
  HorizontalAlignment="Left"  
  Grid.Row="1" 
  VerticalAlignment="Top" 
  x:Name="ItemsListView"
  Margin="39,20,0,0"
  Width="Auto">
  <ListView.ItemTemplate>
      <DataTemplate>
          <Grid VerticalAlignment="Center" Width="800">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="40*" />
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="20*" />
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Margin="5" TextWrapping="NoWrap" 
                VerticalAlignment="Center"
                Text="{Binding ItemNo}" />

            <TextBlock Grid.Column="1" Margin="5" TextWrapping="Wrap"
                VerticalAlignment="Center"
                Text="{Binding ItemDescription}" />

            <TextBox Grid.Column="2" Margin="5" TextWrapping="NoWrap"
                HorizontalAlignment="Right"       
                VerticalAlignment="Center"
                Text="{Binding Quantity, Mode=TwoWay}" />

            <TextBlock Grid.Column="3" Margin="5" TextWrapping="NoWrap"
                HorizontalAlignment="Right"       
                VerticalAlignment="Center"
                Text="{Binding Price}" />


        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

ItemsSource在

中设置如下  
   private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
   {    
      ...
      this.ExternalDoc.DataContext = orderDetails.orderDetailsHeader;
      this.ItemsListView.ItemsSource = orderDetails.orderDetailsHeader.Lines;

当我更改TextBox for Quantity中的值时,它不会调用PropertyChangedEventHandler - 我无法找出原因!

我更改时,ExternalDoc文本框更新

 
<TextBox x:Name="ExternalDoc" HorizontalAlignment="Left" Grid.Row="1" TextWrapping="Wrap"  VerticalAlignment="Top" Height="27" Width="223" Margin="39,160,0,0" Text="{Binding ExternalDocNo, Mode=TwoWay}"/>

非常感谢任何帮助。感谢

2 个答案:

答案 0 :(得分:0)

我不能完全理解你的问题,但是如果只改变列表中一行的数量属性,那么PropertyChangedEventHandler就不会调用。 您将ObservableCollection的实例绑定到ListView的ItemSource属性。如果要引发Lines属性的PropertyChangedEventHandler,则必须更改ObservableCollection的实例(以便在setter处访问)。 ObservableCollection允许WPF&#34;观察&#34;修改清单。

我尝试了您的示例代码,但我不了解如何从orderDetail获取orderDetailsHeader。我试试这段代码:

WpfApplication2.OrderDetails.OrderDetailsHeader header = new OrderDetails.OrderDetailsHeader(){
                Address = "tata",
                ExternalDocNo = "toto",
                Lines = new ObservableCollection<OrderDetails.OrderDetailsLine>()
            };
            header.Lines.Add(new OrderDetails.OrderDetailsLine()
            {
                ItemDescription = "toto",
                ItemNo = "titi",
                Price = 100,
                Quantity = 2
            });

            this.ExternalDoc.DataContext = header;
            this.ItemsListView.ItemsSource = header.Lines;

使用此代码和xaml,当您更改数量和ExteranlNoDoc时会引发NotifyPropertyChangedEvent。

答案 1 :(得分:0)

将Text绑定到decimal属性时似乎存在问题。尝试将数量类型更改为浮点数,看看是否有效。 更多信息:

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/b0bfe9b9-7634-40d2-8d81-c664498cae6a/winrt-xaml-binding-text-to-decimal-causes