【问题标题】:WPF datagrid - cell updated based on antother cell valueWPF datagrid - 根据另一个单元格值更新单元格
【发布时间】:2017-02-05 18:45:55
【问题描述】:

我想问一下,因为我已经为这个问题苦苦挣扎了好几个小时。

我实现了一个数据网格,并希望根据在同一行中选择的“SP 类型”(组合框)填充“弹簧点的高度”(文本框)。

datagrid row

值已填充,但未显示,我必须单击“弹簧点高度”单元格,然后才会显示一个值。我已经尝试过 UpdateSourceTrigger=LostFocus 而不是 UpdateSourceTrigger=PropertyChanged,但没有奏效。

SelectedPbType 属性包括检索所需值的功能,该值应在选择 SP 类型后立即显示。

抱歉命名不匹配。 SP 类型表示 PB 类型。

能否请您看一下并告诉我我的代码有什么问题?谢谢。

查看:

<dg:DataGrid Height="330" HorizontalAlignment="Stretch" Margin="5,5,0,0" 
                x:Name="autocadCoordinationsDataGrid" VerticalAlignment="Top" RowHeight="25" ColumnWidth="Auto" 
                HeadersVisibility="Column"
                Background="#e6ecff" 
                BorderBrush="Gray" 
                BorderThickness="2" 
                     SelectionMode="Single"
                AutoGenerateColumns="False" 
                IsSynchronizedWithCurrentItem="False"
                CanUserAddRows="false"
                     CanUserDeleteRows="False"
                     CanUserReorderColumns="False" 
                ItemsSource="{Binding CadCoordinates}" 
                SelectedItem="{Binding SelectedCadCoordinate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

                <dg:DataGridTemplateColumn x:Name="cbTempPbType" Header="{lex:Loc EnvironmentCoordinatesGridColumnPbType}" Width="SizeToHeader" >
                    <dg:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="cbPbType" ItemsSource="{Binding Source={StaticResource PbTypes}}" 
                                      SelectedItem="{Binding SelectedPbType, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
                                      DisplayMemberPath="Name" 
                                      IsSynchronizedWithCurrentItem="False"
                                      SelectedValue="{Binding SelectedPbType.Index}"
                                      SelectedValuePath="Index">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="SelectionChanged">
                                        <i:InvokeCommandAction Command="{Binding SelectionPbTypeChangedCommand}"/>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </ComboBox>
                        </DataTemplate>
                    </dg:DataGridTemplateColumn.CellTemplate>
                </dg:DataGridTemplateColumn>

                <dg:DataGridTextColumn 
                    Header="{lex:Loc EnvironmentCoordinatesGridColumnPillarsHeight}" 
                    Width="SizeToHeader"
                    EditingElementStyle="{StaticResource CellEditStyle}"
                    Binding="{Binding PillarsHeight,UpdateSourceTrigger=LostFocus, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, Mode=TwoWay, ValidatesOnExceptions=True}" >
                    <dg:DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="TextWrapping" Value="Wrap"/>
                        </Style>
                    </dg:DataGridTextColumn.ElementStyle>
                </dg:DataGridTextColumn>

            </dg:DataGrid.Columns>
</dg:DataGrid>

型号:

public class CadCoordinatesGrid : ViewModelBase, INotifyPropertyChanged
{
    public event EventHandler Changed;
    private EnvironmentViewModel _viewModel;

    public CadCoordinatesGrid()
    {

    }

    public CadCoordinatesGrid(EnvironmentViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    private ObservableCollection<PbType> _pbType;
    public ObservableCollection<PbType> PbType
    {
        get
        {
            return _pbType;
        }
        set
        {
            _pbType = value;
            OnPropertyChanged("PbType");
        }
    }

    private PbType _selectedPbType;
    public PbType SelectedPbType
    {
        get
        {

            return _selectedPbType;
        }
        set
        {
            if (_viewModel != null) _viewModel.IsDirty = true;

            this.PillarsHeight = EnvironmentHelper.GetPillarHeightFrom(value);
            //OnPropertyChanged("PillarsHeight");

            _selectedPbType = value;
            OnPropertyChanged("SelectedPbType");
        }
    }

    private string _pillarsHeight;
    public string PillarsHeight
    {
        get
        {
            return _pillarsHeight;
        }
        set
        {
            CommonHelper.TryParseDecimal(value);

            if (_viewModel != null) _viewModel.IsDirty = true;
            _pillarsHeight = value;
            OnPropertyChanged(() => PillarsHeight);
        }
    }

    private ICommand selectionPbTypeChangedCommand;
    public ICommand SelectionPbTypeChangedCommand
    {
        get
        {
            if (selectionPbTypeChangedCommand == null)
            {
                selectionPbTypeChangedCommand = new RelayCommand(param => this.PbTypeChangeSelected(),
                    null);
            }
            return selectionPbTypeChangedCommand;
        }
    }

    /// <summary>
    /// Changes the selected.
    /// </summary>
    private void PbTypeChangeSelected()
    {
        OnPropertyChanged(()=> this.PillarsHeight);
    }

    /// <summary>
    /// Called when [property changed].
    /// </summary>
    /// <param name="propertyName">Name of the property.</param>
    protected override void OnPropertyChanged(string propertyName)
    {
        var hander = this.Changed;
        if (hander != null)
        {
            hander(this, EventArgs.Empty);
        }
    }
}

【问题讨论】:

    标签: wpf datagrid cell


    【解决方案1】:

    设置PillarsHeight 属性的是SelectedPbType 属性的设置器。

    摆脱交互触发器和SelectedValue绑定以及ComboBox的SelectedValuePath:

    <ComboBox x:Name="cbPbType" ItemsSource="{Binding Source={StaticResource PbTypes}}" 
              SelectedItem="{Binding SelectedPbType, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
              DisplayMemberPath="Name">
    </ComboBox>
    

    您不应同时绑定 ComboBox 的 SelectedItem 和 SelectedValue 属性。

    【讨论】:

    • 感谢您的回复,但没有帮助。你是对的,SelectedPbType 设置 PillarsHeight 属性。
    • 也许您可以提供一个最小且可重复的样本?:stackoverflow.com/help/mcve。摆脱所有不必要和不相关的基类、类型、静态资源等。设置 DataGridTextColumn 绑定的源属性应该可以工作。
    • 已经不需要了,现在可以了,我把代码都删掉了,你给了我一个思路,非常感谢