繁体   English   中英

当组合框选择更改时,IValueConverter 不更新 Datagrid

[英]IValueConverter not updating Datagrid When Combobox Selection is Changed

我正在尝试使用 MVVM 原理学习和制作应用程序。 我正在做的是这个,

在此处输入图片说明

当尝试实现 2 个 IValueConverters 时,只有其中一个被触发,即只有一个被加载和工作,即 OnStockIconConverter,它在 Datagrid 初始化时加载。

另一个是 CurrencyConverter,它依赖于 ComboBox 切换,当我更改所选值时,它不会对 DataGrid 做出反应。

我已经尝试解决这个问题好几个小时了,对于 MVVM 初学者来说,那里的大部分内容都相当晦涩。

这里的所有其他问题都与我想做的相反。

C#

namespace Coding_Dojo_3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    /// 


    public partial class MainWindow : Window
    {

        public ObservableCollection<StockEntryModel> StockEntriesCollection { get; }

        public MainWindow()
        {

            InitializeComponent();
            var sampleManager = new SampleManager();
            StockEntriesCollection = new ObservableCollection<StockEntryModel>();
            foreach (var stockEntry in sampleManager.CurrentStock.OnStock)
            {
                StockEntriesCollection.Add((new StockEntryModel{SoftwarePackage = stockEntry.SoftwarePackage, Amount = stockEntry.Amount}));
            }
            DataContext = this;
        }

        private void ComboBoxCurrency_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
            SelectedCurrency.Name = text;
            Console.WriteLine("Currency changed to {0}", text);
        }
    }


    public class StockEntryModel : INotifyPropertyChanged
    {
        private object _softwarePackage;
        private int _amount;

        public event PropertyChangedEventHandler PropertyChanged;

        public object SoftwarePackage
        {
            get => _softwarePackage;
            set
            {
                _softwarePackage = value;
                OnPropertyChanged(nameof(SoftwarePackage));
            } 
        }

        public int Amount
        {
            get { return _amount; }
            set
            {
                _amount = value;

                OnPropertyChanged(nameof(Amount));
            }
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }


    public class StockEntryViewModel
    {
        public StockEntryModel NewStockEntryModel { get; set; }

        public StockEntryViewModel()
        {
            NewStockEntryModel = new StockEntryModel();
        }
    }


    public static class SelectedCurrency
    {
        public static String Name;
    }

    public class CurrencyConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var currency = SelectedCurrency.Name;
            switch (currency)
            {

                case "EUR":
                    return CodingDojo4DataLib.Converter.CurrencyConverter.ConvertFromEuroTo(Currencies.EUR,
                            (double)value);
                case "USD":
                    return CodingDojo4DataLib.Converter.CurrencyConverter.ConvertFromEuroTo(Currencies.EUR,
                        (double)value);
                case "GBP":
                    return CodingDojo4DataLib.Converter.CurrencyConverter.ConvertFromEuroTo(Currencies.EUR,
                        (double)value);
                default:
                    return CodingDojo4DataLib.Converter.CurrencyConverter.ConvertFromEuroTo(Currencies.EUR,
                        (double)value);
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class OnStockIconConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is int)
            {
                if ((int)value < 10)
                    return "red";
                if ((int)value > 10 && (int)value < 20)
                    return "orange";
                if ((int)value > 20)
                    return "green";
            }
            return "red";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

XAML

<Window x:Class="Coding_Dojo_3.MainWindow"
        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:Coding_Dojo_3"
        mc:Ignorable="d"
        Title="Coding Dojo 3" Height="400" Width="1024">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.125*" />
            <RowDefinition Height="1*" />
            <RowDefinition Height="0.125*" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Label VerticalAlignment="Top">Currency :</Label>
            <ComboBox AllowDrop="True" Name="ComboBoxCurrency" VerticalAlignment="Top" SelectionChanged="ComboBoxCurrency_SelectionChanged">
                <ComboBoxItem IsSelected="True">EUR</ComboBoxItem>
                <ComboBoxItem>USD</ComboBoxItem>
            </ComboBox>
        </StackPanel>
        <DataGrid Grid.Row="1" 
                  Name="DataGridStock" 
                  AutoGenerateColumns="False"
                  ColumnWidth="*" 
                  x:FieldModifier="public"
                  IsReadOnly="False"
                  CanUserAddRows="True"
                  CanUserDeleteRows="True"
                  ItemsSource="{Binding StockEntriesCollection}">
            <DataGrid.Resources>
                <local:CurrencyConverter x:Key="CurrencyConverter"/>
                <local:OnStockIconConverter x:Key="OnStockIconConverter"/>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding SoftwarePackage.Name}"></DataGridTextColumn>
                <DataGridTextColumn Header="Group" Binding="{Binding SoftwarePackage.Category.Name}"></DataGridTextColumn>
                <DataGridTextColumn Header="Sales Price" Binding="{Binding SoftwarePackage.SalesPrice, NotifyOnTargetUpdated=True, Converter={StaticResource CurrencyConverter}}"></DataGridTextColumn>
                <DataGridTextColumn Header="Purchase Price" Binding="{Binding SoftwarePackage.PurchasePrice, NotifyOnTargetUpdated=True, Converter={StaticResource CurrencyConverter}}"></DataGridTextColumn>
                <DataGridTextColumn Header="Amount" Binding="{Binding Amount}"></DataGridTextColumn>
                <DataGridTextColumn Header="On Stock" Binding="{Binding Amount,  Converter={StaticResource OnStockIconConverter}}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <Button Margin="3">Add</Button>
            <Button Margin="3">Edit</Button>
            <Button Margin="3">Delete</Button>
        </StackPanel>
    </Grid>
</Window>

您应该将视图模型和视图分开,以便您可以使用真正的 MVVM。 现在您的视图同时也是一个视图模型。
为了达到目标,向您的入口模型添加一个方法,例如 NotifyAllChanged 以重新计算所有属性并在您的组合框事件处理程序中调用它。

public class StockEntryModel : INotifyPropertyChanged
{
    ...

    public void NotifyAllChanged()
    {
        OnPropertyChanged(string.Empty);
    }
}

       private void ComboBoxCurrency_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
        SelectedCurrency.Name = text;
        Console.WriteLine("Currency changed to {0}", text);

        StockEntriesCollection?.ForEach(entry=>entry.NotifyAllChanged()); // <==
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM