目前我正在使用c#学习MVVM和WPF。我正在使用MVVM 8、Net 7.0和WPF UI的社区工具包(设计)包和VS 2022。我试图在一个页面上显示一个列表,其中包含从同一个接口继承的不同项目。在同一个页面上,我想用一个用户控件编辑SelectedItem。为此,我目前正在将用户控件直接添加到页面中,使用绑定到SelectedItem。它显示UserControl中的值,但如果我更改某些值,则当我从列表中选择不同的项目时,listview的selectedItem不再更新。此外,我想使用DataTemplate确定的不同usercontrol编辑不同的模型。请看以下图片:
这里是选择的项目1没有编辑
这里是选择的项目2没有编辑
这里是再次选择的项目1,但项目2编辑见第一个文本框,但SelectedItem不再改变
以下是我的两个问题:
1.如何编辑选定的项目并在编辑后更改选定的项目?是否必须实现某种逻辑来处理此问题?
1.如何使用通用控件(如contentcontrol)根据使用数据模板的类型来显示用户控件?如何处理绑定(例如,我必须绑定到content属性的contentcontrol)?在这种情况下,contentcontrol是否是正确的选择?
ListPage.xaml
<ui:UiPage x:Class="EditListItem.Views.Pages.ListPage"
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:local="clr-namespace:EditListItem.Views.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:userControls="clr-namespace:EditListItem.Views.UserControls"
Title="ListPage"
d:DataContext="{d:DesignInstance local:ListPage, IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
d:Background="{DynamicResource ApplicationBackgroundBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding ViewModel.Actions, Mode=TwoWay}"
SelectionMode="Single"
SelectedItem="{Binding ViewModel.SelectedAction, Mode=TwoWay}">
</ListView>
<userControls:TransactionUserControl Grid.Column="1" Transaction="{Binding ViewModel.SelectedAction, Mode=TwoWay}"/>
</Grid>
<WrapPanel Grid.Row="1">
<Button Content="Deposit" Command="{Binding ViewModel.AddDepositCommand}" />
<Button Content="Withdrawal" Command="{Binding ViewModel.AddWithdrawalCommand}" />
<Label Content="{Binding ViewModel.SelectedAction, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</WrapPanel>
</Grid>
</ui:UiPage>
ListPage.xaml.cs
public partial class ListPage : INavigableView<ViewModels.ListViewModel>
{
public ViewModels.ListViewModel ViewModel {
get;
}
public ListPage(ViewModels.ListViewModel viewModel)
{
ViewModel = viewModel;
InitializeComponent();
}
}
ListViewModel.cs
public partial class ListViewModel : ObservableObject, INavigationAware
{
private bool _isInitialized = false;
public ObservableCollection<IAction> Actions { get; set; } = new();
[ObservableProperty] private IAction? _selectedAction;
public ListViewModel()
{
Actions = new() {
new Deposit() {
Id = "1",
Timestamp = "00000000",
Amount = 0,
Symbol = "Symbol1"
},
new Withdrawal() {
Id = "2",
Timestamp = "00000000",
Amount = 0,
Symbol = "Symbol2"
}
};
}
[RelayCommand]
private async void AddDeposit()
{
Actions.Add(new Deposit());
}
[RelayCommand]
private async void AddWithdrawal()
{
Actions.Add(new Withdrawal());
}
}
下面是我想使用的控件:
TransactionUserControl.xaml
<UserControl x:Class="EditListItem.Views.UserControls.TransactionUserControl"
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:userControls="clr-namespace:EditListItem.Views.UserControls"
d:Background="{DynamicResource ApplicationBackgroundBrush}"
d:Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="400" >
<StackPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBox Text="{Binding Transaction.Id, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<TextBox Text="{Binding Transaction.Timestamp, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<TextBox Text="{Binding Transaction.Amount, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<TextBox Text="{Binding Transaction.Symbol, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</StackPanel>
</UserControl>
TransactionUserControl.xaml.cs
public partial class TransactionUserControl
{
private static DependencyProperty _transactionProperty = DependencyProperty.Register(nameof(Transaction), typeof(IAction), typeof(TransactionUserControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public IAction Transaction {
get => (IAction)GetValue(_transactionProperty);
set => SetValue(_transactionProperty, value);
}
public TransactionUserControl()
{
//DataContext = this;
InitializeComponent();
}
}
最后,接口存款和Withdrawal继承自。模型不是DependencyObjects,仅为纯Model:
public interface IAction
{
public string Id { get; set; }
public string Timestamp { get; set; }
public double Amount { get; set; }
public string Symbol { get; set; }
}
public record Deposit : IAction
{
public string Id { get; set; }
public string Timestamp { get; set; }
public double Amount { get; set; }
public string Symbol { get; set; }
}
1条答案
按热度按时间pkmbmrz71#
将
Desposit
类更改为以下内容,以便在更改其属性时更新UI: