我有一个财务应用程序,用户可以在其中输入发票金额到DataGrid中。 DataGrid绑定了一个ObservableCollection金额,每个金额由Gross,VAT rate,VAT和Net组成。要求是每当用户输入四个值中的两个时,另外两个将由软件计算并显示。因此,对于每个列,CellEditEnding事件(增值税率为SelecChanged,这是一个ComboBox)上有一个事件处理程序,当用户更改它们的值时,它应该触发。
我的问题是,事件不仅触发用户交互,而且总是在值发生变化时触发,例如作为计算的结果。有没有办法只检测用户所做的更改,即仅在用户更改值时才触发事件?
以下是代码:
XAML
<DataGrid
x:Name="dgvBetraege"
Grid.Row="3"
Grid.Column="1"
Grid.ColumnSpan="2"
Focusable="True"
TabIndex="3"
Margin="0,0,0,3"
ItemsSource="{Binding currEinnahme.Betraege, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
AlternationCount="2"
RowHeight="24"
AlternatingRowBackground="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
HorizontalGridLinesBrush="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
VerticalGridLinesBrush="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
SelectionMode="Single"
SelectionUnit="FullRow"
SelectedItem="{Binding currBetrag, Mode=TwoWay}"
AutoGenerateColumns="False"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
RenderTransformOrigin="0.5,0.5"
CanUserAddRows="False"
HeadersVisibility="Column"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Disabled"
CellEditEnding="Betrag_CellEditEnding">
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Path=BetragID}"
Visibility="Hidden">
</DataGridTextColumn>
<DataGridTextColumn
x:Name="colBetBtto"
Header="Brutto"
HeaderStyle="{StaticResource DataGridHeaderRightAligned}"
Width="*"
CellStyle="{StaticResource DataGridCellRightAligned}"
Binding="{Binding Path=BttoBetrag, Mode=TwoWay, StringFormat=N2, UpdateSourceTrigger=PropertyChanged}">
</DataGridTextColumn>
<DataGridTemplateColumn
x:Name="colBetUSt"
Header="USt %"
HeaderStyle="{StaticResource DataGridHeaderRightAligned}"
Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="mod:UStSatz">
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.UStSaetze, Mode=OneWay}"
DisplayMemberPath="UStProz"
HorizontalAlignment="Stretch"
TextBlock.TextAlignment="Right"
ItemStringFormat="{}{0,19:N1} %"
SelectedItem="{Binding USt, Mode=TwoWay, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"
SelectionChanged="ComboBox_SelectionChanged">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
x:Name="colBetUStB"
Header="USt"
HeaderStyle="{StaticResource DataGridHeaderRightAligned}"
Width="*"
CellStyle="{StaticResource DataGridCellRightAligned}"
Binding="{Binding Path=UStBetrag, Mode=TwoWay, StringFormat=N2, UpdateSourceTrigger=PropertyChanged}">
</DataGridTextColumn>
<DataGridTextColumn
x:Name="colBetNtto"
Header="Netto"
HeaderStyle="{StaticResource DataGridHeaderRightAligned}"
Width="*"
CellStyle="{StaticResource DataGridCellRightAligned}"
Binding="{Binding Path=NttoBetrag, StringFormat=N2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</DataGridTextColumn>
</DataGrid.Columns>
代码背后:
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox s = (ComboBox)e.Source;
vmEinnahme.CalculateBetrag((int)enumBetColIndex.UstSatz);
e.Handled = true;
}
private void Betrag_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
vmEinnahme.CalculateBetrag(e.Column.DisplayIndex);
}
感谢您的帮助!
答案 0 :(得分:1)
您可以在进行计算时分离CellEditEnding
,并在进行计算时将其附加。如果以这种方式执行此操作,则在更改计算中的值时不会触发CellEditEnding
事件。
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
dgvBetraege.CellEditEnding -= Betrag_CellEditEnding;
ComboBox s = (ComboBox)e.Source;
vmEinnahme.CalculateBetrag((int)enumBetColIndex.UstSatz);
dgvBetraege.CellEditEnding += Betrag_CellEditEnding;
e.Handled = true;
}
private void Betrag_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
dgvBetraege.CellEditEnding -= Betrag_CellEditEnding;
vmEinnahme.CalculateBetrag(e.Column.DisplayIndex);
dgvBetraege.CellEditEnding += Betrag_CellEditEnding;
}
修改强>
另一种解决方案是使用bool
来区分用户和程序操作。可能看起来像这样。
private bool _isCalculating = false;
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_isCalculating = true;
ComboBox s = (ComboBox)e.Source;
vmEinnahme.CalculateBetrag((int)enumBetColIndex.UstSatz);
_isCalculating = false;
e.Handled = true;
}
private void Betrag_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if(!_isCalculating)
{
vmEinnahme.CalculateBetrag(e.Column.DisplayIndex);
}
}