如何自动更新ListBox中的内容

时间:2012-06-08 08:44:37

标签: wpf listbox automation wpf-controls itemscontrol

我正在研究WPF Windows应用程序。我正在使用ListBox来查看/编辑内容。我正在做计算的东西。所以我希望如果我更改一个项的值,它会自动更改计算而不添加额外的按钮来重新生成它。

<ListBox ItemsSource="{Binding CustomSalesProducts, Mode=TwoWay}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
        <ItemsControl.Template>
            <ControlTemplate TargetType="ItemsControl">
                <Border>
                    <ScrollViewer VerticalScrollBarVisibility="Auto">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel CanHorizontallyScroll="True" CanVerticallyScroll="True" Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="SalesGrid" Background="White">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <controls:HeaderedContentControl Header="{Binding ProductName, Mode=TwoWay}" Margin="{DynamicResource Margin4}" Style="{DynamicResource HeaderedContentControlStyle}" HorizontalContentAlignment="Right">
                    </controls:HeaderedContentControl>
                    <TextBox Text="{Binding OrderQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Margin="{StaticResource Margin4}" Style="{DynamicResource MiniTextBoxStyle}" ToolTip="Quantity" />
                    <TextBlock Text="{Binding UnitSalePrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Price"/>
                    <TextBox Text="{Binding Discount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="1" Margin="{StaticResource Margin4}" Style="{DynamicResource MiniTextBoxStyle}" ToolTip="Discount"/>
                    <TextBlock Text="{Binding TaxAmount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Tax Amount"/>
                    <TextBlock Text="{Binding LineTotal, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Total"/>

                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ListBox>

修改

我尝试了触发器,但它在列表框中不起作用

像:

<TextBox Text="{Binding OrderQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="{StaticResource Margin4}" Style="{DynamicResource MiniTextBoxStyle}" ToolTip="Quantity" >
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="LostFocus">
                                    <i:InvokeCommandAction Command="{Binding RefreshProduct}"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </TextBox>

由于

1 个答案:

答案 0 :(得分:1)

所以这就是我的建议:

  • 确保您的Model类(例如CustomSalesProduct)正在实现INotifyPropertyChanged接口。
  • 当您的OrderQty属性值更改时(例如,当用户在TextBox中键入另一个数量时),然后调用您的方法来计算属性集中的总数。这将自动刷新视图中的LineTotal值。

编辑:如果您决定使用MVVM Design Pattern,那么:

创建一个ViewModel类,如:

public class CustomSalesViewModel
{
   public ObservableCollection<CustomSalesProduct> CustomSalesProducts {get;set;}

   public CustomSalesViewModel()
  {
    //Initialize your collection in constructor
    CustomSalesProducts = new ObservableCollection<CustomSalesProduct>();
    //Populate list
    CustomSalesProducts.Add(new CustomSalesProduct(){....});
    //.... Add rest of items
  }
}

然后将View的DataContext设置为CustomSalesViewModel的实例。 您可以在View(XAML)的代码隐藏的构造函数中执行此操作,如:

DataContext = new CustomSalesViewModel();

这里是示例类:

public class CustomSalesProduct : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int _orderQty;

        public int OrderQty
        {
            get { return _orderQty; }
            set
            {
                _orderQty = value;
                OnPropertyChanged("OrderQty");
                CalcTotal();
            }
        }

        private double _unitSalePrice;

        public double UnitSalePrice
        {
            get { return _unitSalePrice; }
            set
            {
                _unitSalePrice = value;
                OnPropertyChanged("UnitSalePrice");
            }
        }

        private double _discount;

        public double Discount
        {
            get { return _discount; }
            set
            {
                _discount = value;
                OnPropertyChanged("Discount");
            }
        }

        private double _taxAmount;

        public double TaxAmount
        {
            get { return _taxAmount; }
            set
            {
                _taxAmount = value;
                OnPropertyChanged("TaxAmount");
            }
        }

        private double _lineTotal;

        public double LineTotal
        {
            get { return _lineTotal; }
            set
            {
                _lineTotal = value;
                OnPropertyChanged("LineTotal");
            }
        }

        private string _productName;

        public string ProductName
        {
            get { return _productName; }
            set
            {
                _productName = value;
                OnPropertyChanged("ProductName");
            }
        }

        public void CalcTotal()
        {
            LineTotal = OrderQty*UnitSalePrice*(1 - Discount);
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
相关问题