1

如果愿意,请耐心等待,我是 WPF MVVM 开发的新手。

我正在处理的实用程序(WPF 客户端应用程序)包含一个 4 列数据网格,它在指定的时间段内向用户显示当前可用的数据。返回的记录可能包含完成记录所需的全部或部分数据。用户应该能够修改缺失的部分或完全添加新行以填充缺失的记录。4 列中的 3 列包含只有有效选项的组合框。组合框是级联的,因此第一个组合确定组合 2 和 3 的内容。第 4 列是简单的价格列。

我已经设法让网格与默认返回数据完美配合。组合框正确填充,并将当前记录的值显示为组合中的选定项。

我的问题是添加新行。我一直在努力完成这个内联。这意味着用户单击列表底部的空白行或使用标签,然后将新行添加到集合中接受输入。第一个组合填充在空行中,但选择一个值不会将更改级联到其他 2 个组合。不过,它在填充的行中起作用。

有道理?我可能错过了一些如此愚蠢的简单事情,以至于当有人指出时我会踢自己,但现在我正在撕掉我剩下的小头发。

那么,是否可以让新用户通过跳到下一行来添加一行?我需要什么特别的东西来连接新行中的级联组合框吗?

谢谢!

这是我的 XAML(剥离后基本上是伪代码,所以不要介意拼写错误):

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApplication2"
    mc:Ignorable="d"
    d:DesignHeight="768"
    d:DesignWidth="1024">

<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>
<Grid>
    <StackPanel>
        <DataGrid AutoGenerateColumns="False"
                    ItemsSource="{Binding Prices}"
                    SelectedItem="{Binding SelectedPrice}"
                    CanUserAddRows="True">
            <DataGrid.Columns>


                <!--  Price Group  -->
                <DataGridTemplateColumn MinWidth="120"
                                        Header="Price Group">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="cboPriceGroup"
                                        ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.PriceGroups}"
                                        DisplayMemberPath="Name"
                                        SelectedItem="{Binding PriceGroupObject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <!--  Option 1  -->
                <DataGridTemplateColumn MinWidth="120"
                                        Header="Option1">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="cboOption1"
                                        ItemsSource="{Binding PriceGroupObject.Options1}"
                                        DisplayMemberPath="Code"
                                        SelectedValuePath="Id"
                                        SelectedValue="{Binding Option1Id, Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <!--  Option 2  -->
                <DataGridTemplateColumn MinWidth="120"
                                        Header="Option2">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="cboOption2"
                                        ItemsSource="{Binding PriceGroupObject.Options2}"
                                        DisplayMemberPath="Code"
                                        SelectedValuePath="Id"
                                        SelectedValue="{Binding Option2Id, Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <!--  Price  -->
                <DataGridTemplateColumn MinWidth="120"
                                        Header="Price">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="txtPrice"
                                        Text="{Binding Price, Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>

</Grid>

这是 ViewModel:

    // ViewModelBase implements INotifyPropertyChanged
public class MainWindowViewModel : ViewModelBase    
{
    #region Declarations
    // Comes From Backend.Services
    private IPriceListService _PriceListService;

    private ObservableCollection<Price> _Prices;
    private Price _SelectedPrice;

    private IEnumerable<PriceGroup> _PriceGroups;
    private PriceGroup _SelectedPriceGroup;

    // Same for Options1, Options2

    #endregion

    #region Properties

    public ObservableCollection<Price> Prices
    {
        get { return _Prices; }
        set
        {
            if (_Prices != value)
            {
                _Prices = value;
                OnPropertyChanged("Prices");
            }
        }
    }
    public Price SelectedPrice
    {
        get { return _Price; }
        set
        {
            if (_Price != value)
            {
                _Price = value;
                OnPropertyChanged("SelectedPrice");
            }
        }
    }

    // Same for PriceGroups, Options1, Options2

    #endregion

    #region Constructor
    public MainViewModel()
        : this(new FakePriceListService())
    {

    }
    // Constructor
    public MainViewModel(IPriceListService priceListService)
    {
        _PriceListService = priceListService;
        InitializeViewModel();
    }

    protected override void InitializeViewModel()
    {
        // Test ID
        LoadFuturesPrices(12345);
        LoadPriceGroups();
        base.InitializeViewModel();
    }
    #endregion

    #region Methods

    void LoadFuturesPrices(short FinancialPeriodId)
    { 
        Prices = _PriceListService.GetFuturesPriceList(FinancialPeriodId);
    }

    void LoadPriceGroups()
    {
        PriceGroups = _PriceListService.GetPriceGroups();
    }

    void PriceGroupSelected(string PriceGroupId)
    {
        SelectedPriceGroup = (from p in PriceGroups where p.Name == PriceGroupId select p).SingleOrDefault();
    }
    #endregion

}
4

0 回答 0