【发布时间】:2022-01-12 16:30:02
【问题描述】:
我是 MVVM 的新手,我似乎找不到我的问题的答案..
我有 2 个视图(Caixa 和 CaixaDetalhes),在 Caixa 视图中,我有一个显示所有 Caixas 的数据网格,在第二个视图中显示详细信息,用户可以“CRUD”,但我不想在何时关闭视图使用对话结果更新或添加。
我的观点:
AssistenciasCaixas:
<DataGrid x:Name="dgCaixas" Grid.Row="1" Style="{StaticResource DataGridResultados}" ItemsSource="{Binding Caixas}" SelectedItem="{Binding CaixaSelecionado}" RowHeight="25" Background="White" >
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Visibility="Hidden" Binding="{Binding Id}"/>
<DataGridTextColumn Header="PostoID" Visibility="Hidden" Binding="{Binding Posto.ID}"/>
<DataGridTextColumn Header="IdUtilizador" Visibility="Hidden" Binding="{Binding IdUtilizador}"/>
<DataGridTextColumn Header="Posto" Width="200" Binding="{Binding Posto.Descricao}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Data Caixa" Width="90" Binding="{Binding DataCaixa,StringFormat={}\{0:dd/MM/yyyy\}}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Data Eliminado" Width="100" Binding="{Binding DataEliminado, StringFormat={}\{0:dd/MM/yyyy\}}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Motivo" Width="*" Binding="{Binding Motivo}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Nº Caixa" Width="70" Binding="{Binding NumCaixa}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Exportado" Width="100" Binding="{Binding Exportado}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Observações" Width="200" Binding="{Binding Obs}" CanUserReorder="False" CanUserResize="False" CanUserSort="False" FontSize="15" IsReadOnly="True"/>
<DataGridTextColumn Header="Utilizador" Visibility="Hidden" Binding="{Binding IdUtilizador}"/>
</DataGrid.Columns>
</DataGrid>
CaixaDetalhes
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
<RowDefinition Height="150"/>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Posto:" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" Margin="0,-5,0,0" />
<ComboBox Grid.Column="0" x:Name="comboBoxPostos" VerticalAlignment="Bottom" HorizontalAlignment="Center" Width="300" Margin="0,0,0,5" Style="{DynamicResource ComboBoxProblemas}" ItemsSource="{Binding Postos}" SelectedItem="{Binding Detalhes.Posto}" SelectedValue="{Binding Detalhes.Posto.ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Descricao"/>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Stroke="#FF00256D" />
<Label Grid.Column="1" Content="Exportado para o Olisoft?" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="35,0,0,0" Style="{StaticResource lblEditarForms}" FontSize="20"/>
<CheckBox x:Name="cbExportado" Grid.Column="1" IsChecked="{Binding Detalhes.Exportado, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,20,0">
<CheckBox.LayoutTransform>
<ScaleTransform ScaleX="1.5" ScaleY="1.5" />
</CheckBox.LayoutTransform>
</CheckBox>
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="1" Stroke="#FF00256D" Grid.ColumnSpan="2" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Data do Caixa:" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" FontSize="20"/>
<DatePicker x:Name="dtPickerDataCaixa" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,15" FirstDayOfWeek="Monday" DisplayDateStart="2015-01-01" CalendarStyle="{StaticResource resizedCalendarItem}" SelectedDate="{Binding Detalhes.DataCaixa, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Stroke="#FF00256D" />
<Label Grid.Column="1" Content="Data Eliminado:" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" FontSize="20"/>
<DatePicker x:Name="dtPickerDataEliminado" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,15" FirstDayOfWeek="Monday" DisplayDateStart="2015-01-01" CalendarStyle="{StaticResource resizedCalendarItem}" SelectedDate="{Binding Detalhes.DataEliminado, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Rectangle Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Stroke="#FF00256D" />
<Label Grid.Column="2" Content="Número do Caixa:" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" FontSize="20"/>
<TextBox x:Name="txtNumCaixa" Grid.Column="2" Height="28" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,15" Width="200" MaxLines="1" FontSize="15" Text="{Binding Detalhes.NumCaixa, UpdateSourceTrigger=PropertyChanged}"/>
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="1" Stroke="#FF00256D" Grid.ColumnSpan="3" />
</Grid>
<Label Grid.Row="2" Content="Motivo" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" FontSize="20" Margin="0,-6,0,0"/>
<TextBox Grid.Row="2" x:Name="richTextBoxMotivo" Height="100" Width="655" FontFamily="Calibri" FontSize="18" VerticalAlignment="Bottom" BorderBrush="#AAAAAA" BorderThickness="1.5" Margin="0,0,0,8" Text="{Binding Detalhes.Motivo, UpdateSourceTrigger=PropertyChanged}"/>
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="1" Stroke="#FF00256D" Grid.Row="2" />
<Label Grid.Row="3" Content="Observações" VerticalAlignment="Top" HorizontalAlignment="Center" Style="{StaticResource lblEditarForms}" FontSize="20" Grid.RowSpan="2"/>
<TextBox Grid.Row="3" x:Name="richTextBoxObservacoes" Height="100" Width="655" FontFamily="Calibri" FontSize="18" VerticalAlignment="Bottom" BorderBrush="#AAAAAA" BorderThickness="1.5" Margin="0,0,0,10" Text="{Binding Detalhes.Obs, UpdateSourceTrigger=PropertyChanged}" />
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="1" Stroke="#FF00256D" Grid.Row="3" />
<UniformGrid Grid.Row="4" Columns="4" Height="70" Background="White" >
<Button x:Name="btnGravar" Style="{StaticResource BotaoGridOperacoes}" CommandParameter="{Binding}" Command="{Binding Gravar}">
<DockPanel LastChildFill="True" Width="115">
<Image Source="../../Imagens/save32black.png" Stretch="Fill" Width="32" Height="32" />
<TextBlock x:Name="txtBtnGravar" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FF00256D" Text="{Binding Path=AddSave, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"></TextBlock>
</DockPanel>
</Button>
<Button Style="{StaticResource BotaoGridOperacoes}">
<DockPanel LastChildFill="True" Width="115">
<Image Source="../../Imagens/new32Black.png" Stretch="Fill" Width="32" Height="32" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FF00256D">Novo</TextBlock>
</DockPanel>
</Button>
<Button Style="{StaticResource BotaoGridOperacoes}" >
<DockPanel VerticalAlignment="Stretch" Width="125">
<Image Source="../../Imagens/bin2.png" Stretch="Fill" Width="32" Height="32"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FF00256D">Eliminar</TextBlock>
</DockPanel>
</Button>
<Button x:Name="btnSair" Style="{StaticResource BotaoGridOperacoes}" CommandParameter="{Binding}" Command="{Binding Sair}">
<DockPanel VerticalAlignment="Stretch" Width="100">
<Image Source="/HelpDesk Assist;component/Avancado/Imagens/exit32.png" Stretch="Fill" Width="32" Height="32" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FF00256D">Sair</TextBlock>
</DockPanel>
</Button>
</UniformGrid>
</Grid>
我的模特:
财萨:
public class Caixa : BaseNotifyPropertyChanged
{
private int _id;
private Posto _posto;
private DateTime _dataCaixa;
private DateTime _dataEliminado;
private string _motivo;
private int _numCaixa;
private bool _exportado;
private string _obs;
private int _idUtilizador;
public int Id
{
get => _id;
set => SetField(ref _id, value);
}
public Posto Posto
{
get => _posto;
set => SetField(ref _posto, value);
}
public DateTime DataCaixa
{
get => _dataCaixa;
set => SetField(ref _dataCaixa, value);
}
public DateTime DataEliminado
{
get => _dataEliminado;
set => SetField(ref _dataEliminado, value);
}
public string Motivo
{
get => _motivo;
set => SetField(ref _motivo, value);
}
public int NumCaixa
{
get => _numCaixa;
set => SetField(ref _numCaixa, value);
}
public bool Exportado
{
get => _exportado;
set => SetField(ref _exportado, value);
}
public string Obs
{
get => _obs;
set => SetField(ref _obs, value);
}
public int IdUtilizador
{
get => _idUtilizador;
set => SetField(ref _idUtilizador, value);
}
}
我的视图模型:
CaixasViewModel
public class CaixasViewModel : BaseNotifyPropertyChanged
{
public ObservableCollection<Caixa> Caixas { get; private set; }
public CaixasViewModel()
{
int utilizadorAtual = Properties.Settings.Default.userID;
Caixas = new ObservableCollection<Caixa>();
Caixas = CaixaData.GetCaixasUtilizador(utilizadorAtual);
}
private Caixa _caixaSelecionado;
public Caixa CaixaSelecionado
{
get { return _caixaSelecionado; }
set
{
SetField(ref _caixaSelecionado, value);
Delete.RaiseCanExecuteChanged();
Edita.RaiseCanExecuteChanged();
}
}
public DeleteCaixa Delete { get; private set; } = new DeleteCaixa();
public EditaCaixa Edita { get; private set; } = new EditaCaixa();
public NovoCaixa Novo { get; private set; } = new NovoCaixa();
public class DeleteCaixa : BaseCommand
{
public override bool CanExecute(object parameter)
{
return parameter is CaixasViewModel viewModel && viewModel.CaixaSelecionado != null;
}
public override void Execute(object parameter)
{
CaixasViewModel viewModel = (CaixasViewModel)parameter;
CaixaData.DeleteCaixa(viewModel.CaixaSelecionado.Id);
_ = viewModel.Caixas.Remove(viewModel.CaixaSelecionado);
}
}
public class NovoCaixa : BaseCommand
{
public override bool CanExecute(object parameter)
{
return parameter is CaixasViewModel;
}
public override void Execute(object parameter)
{
CaixasViewModel viewModel = (CaixasViewModel)parameter;
Caixa caixa = new Caixa
{
DataCaixa = DateTime.Now,
DataEliminado = DateTime.Now
};
CaixasDetalhesViewModel caixaDetalhes = new CaixasDetalhesViewModel(caixa);
DetalhesCaixa dc = new DetalhesCaixa(caixaDetalhes)
{
Owner = Application.Current.MainWindow
};
_ = dc.ShowDialog();
if (dc.DialogResult.HasValue && dc.DialogResult.Value)
{
viewModel.Caixas.Add(caixa);
viewModel.CaixaSelecionado = caixa;
}
}
}
public class EditaCaixa : BaseCommand
{
public override bool CanExecute(object parameter)
{
return parameter is CaixasViewModel viewModel && viewModel.CaixaSelecionado != null;
}
public override void Execute(object parameter)
{
CaixasViewModel viewModel = (CaixasViewModel)parameter;
CaixasDetalhesViewModel caixaDetalhes = new CaixasDetalhesViewModel(viewModel.CaixaSelecionado);
DetalhesCaixa detCaixa = new DetalhesCaixa(caixaDetalhes)
{
Owner = Application.Current.MainWindow
};
_ = detCaixa.ShowDialog();
}
}
}
CaixasDetalhesViewModel:
public class CaixasDetalhesViewModel : BaseNotifyPropertyChanged
{
public ObservableCollection<Posto> Postos { get; set; }
public Caixa Detalhes { get; set; }
public CaixasDetalhesViewModel(Caixa detalhes)
{
Postos = new ObservableCollection<Posto>();
Postos = PostoData.GetPostosSimples();
Detalhes = detalhes;
EscolheFinal();
}
private string _addSave = "Inserir";
public string AddSave
{
get => _addSave;
set
{
_addSave = value;
RaisePropertyChanged("AddSave");
}
}
public void EscolheFinal()
{
AddSave = Detalhes.Id == 0 ? "Inserir" : "Gravar";
}
public Action DialogResult { get; set; }
public Action CloseWindow { get; set; }
public GravarCaixa Gravar { get; private set; } = new GravarCaixa();
public SairCaixa Sair { get; private set; } = new SairCaixa();
public class GravarCaixa : BaseCommand
{
public override bool CanExecute(object parameter)
{
return parameter is CaixasDetalhesViewModel viewModel;
}
public override void Execute(object parameter)
{
CaixasDetalhesViewModel viewModel = (CaixasDetalhesViewModel)parameter;
viewModel.Detalhes.IdUtilizador = Properties.Settings.Default.userID;
CaixaData.AdicionaCaixa(viewModel.Detalhes);
viewModel.EscolheFinal();
viewModel.DialogResult();
}
}
public class SairCaixa : BaseCommand
{
public override bool CanExecute(object parameter)
{
return parameter is CaixasDetalhesViewModel viewModel;
}
public override void Execute(object parameter)
{
CaixasDetalhesViewModel viewModel = (CaixasDetalhesViewModel)parameter;
viewModel.CloseWindow();
}
}
}
总体:
我可以使用 DialogResult 进行 CRUD,但我需要能够在 CaixaDetalhes 视图中插入/更新/删除“Caixa”而不关闭视图
编辑: 如何仅在单击保存按钮时更新 Caixa 模型?我尝试使用“UpdateSourceTrigger=Explicit”,但尝试更改 Caixa 时没有任何反应..
我没有使用任何框架,如果可能的话,我想保持这种状态
【问题讨论】:
-
您必须创建一个中间项目进行编辑。然后 save 命令通过将数据复制到集合中的真实模型来提交更改。就这样。创建时,您创建一个空白项目,并且仅在“保存”时将其添加到集合中。在编辑时,创建原始项目的副本,对其进行编辑并将其复制回“保存”。
-
但是我该怎么做呢?当我像这样关闭 CaixasDetalhes 视图时,我正在添加到 CaixasViewModel 中的 observableCollection:“if (dc.DialogResult.HasValue && dc.DialogResult.Value) { viewModel.Caixas.Add(caixa); viewModel.CaixaSelecionado = caixa; }”。如何通过 CaixasDetalhesViewModel 添加数据?我可以很好地添加/更新到数据库,但不能添加/更新到 observableCollection
-
CaixasDetalhesViewModel 显然需要对 Caixas 集合的引用。你在哪里显示对话框?
-
这并不重要。创建对话框时,您还创建了 CaixasDetalhesViewModel 的实例。只需将 Caixas 属性添加到 CaixasDetalhesViewModel 并在将其设置到对话框上下文之前将其分配,或者将 CaixasViewModel 的引用传递给 CaixasDetalhesViewModel 并让 CaixasDetalhesViewModel 调用 AddNewCaixa(Caixa newItem) 方法,该方法实际上添加了项目。
-
第三个选项,将一组 Add/Edit/Remove ICommand 或委托传递给 CaixasDetalhesViewModel。优点是 CaixasViewModel 可能对 CaixasDetalhesViewModel 保持未知。我认为第三种选择是最好的。