簡體   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