![](/img/trans.png)
[英]C# wpf how to get data bind value from another class(user control) in main window
[英]C# WPF How i can pass data from User Control to Main VM
我正在嘗試為員工、訂單、部門編寫一個會計應用程序。
我有一個元素編輯器 window,其中根據所選元素(員工/訂單/部門)替換所需的用戶控件
面臨將數據從視圖 Model 用戶控件傳遞到父視圖 window 的視圖 Model 的問題。
如何將 SelectedEmployee 從 EmployeeEditViewModel 傳遞到 CreateEditViewModel?
父窗口 CreateEditViewModel
public class CreateEditWindowViewModel : BaseViewModel
{
private BaseViewModel selectedViewModel;
private object selectedItem;
private IMessenger messenger;
// Repositories
private IRepository<Employee> employeeRepository;
private IRepository<Order> orderRepository;
private IRepository<Subdivision> subdivisionRepository;
// Commands
public ICommand CloseWindowCommand { get; private set; }
public ICommand MaximizeWindowCommand { get; private set; }
public ICommand MinimizeWindowCommand { get; private set; }
public ControllCommand SaveItemCommand { get; private set; }
public CreateEditWindowViewModel(IMessenger messenger)
{
employeeRepository = new EmployeeRepository();
subdivisionRepository = new SubdivisionRepository();
orderRepository = new OrderRepository();
this.messenger = messenger;
messenger.Subscribe<RequestIdMessage>(this, GetId);
messenger.Subscribe<EditItemMessage>(this, GetItem);
CloseWindowCommand = new CloseWindowCommand(this);
MaximizeWindowCommand = new MaximizeWindowCommand(this);
MinimizeWindowCommand = new MinimizeWIndowCommand(this);
SaveItemCommand = new ControllCommand(SaveItem);
windowId = -1;
}
xaml 創建編輯視圖
<Window x:Class="MerryWaterCarrier.View.CreateEditWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MerryWaterCarrier.View"
xmlns:viewedit="clr-namespace:MerryWaterCarrier.View.EditorWindow"
DataContext="{Binding Path=CreateEditWindowViewModel, Source={StaticResource ViewModelLocator}}"
mc:Ignorable="d"
Title="CreateEditWindow" Height="450" Width="800"
Background="#36363F"
WindowStyle="None"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="30*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="30*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Border Margin="5,0,5,0" Background="#252525" Grid.Row="0" Grid.Column="1">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Command="{Binding MinimizeWindowCommand}"
Width="20" Height="20"
Content="🗕" Background="Transparent"
BorderThickness="0" Foreground="Gray"
FontWeight="Bold"
Margin="0,0,0,-3"/>
<Button Command="{Binding MaximizeWindowCommand}"
Width="20" Height="20"
Content="⬜" Background="Transparent"
BorderThickness="0" Foreground="Gray"
FontWeight="Bold"
Margin="0,0,0,-5"/>
<Button Command="{Binding CloseWindowCommand}"
Width="20" Height="20"
Content="╳" Background="Transparent"
BorderThickness="0" Foreground="Gray"
FontWeight="Bold"/>
</StackPanel>
</Border>
<ToolBar Grid.Row="1" Grid.Column="1">
<Button Content="Сохранить" Command="{Binding SaveItemCommand}"/>
</ToolBar>
<ContentControl Content="{Binding SelectedViewModel}" Grid.Column="1" Grid.Row="1">
</ContentControl>
</Grid>
用戶控制員工 ViewModel
public class EmployeeEditViewModel : BaseViewModel
{
private EmployeesCollection employeesCollection;
private Employee selectedEmployee;
private string family;
private string name;
private string patronymic;
private DateTime birthDate;
private Gender gender;
private int subdivisionId;
public EmployeeEditViewModel()
{
employeesCollection = EmployeesCollection.employeesCollection;
}
public ObservableCollection<Employee> Employees
{
get
{
return employeesCollection.Employees;
}
set
{
employeesCollection.Employees = value;
OnPropertyChanged("Employees");
}
}
public string Family
{
get
{
return family;
}
set
{
family = value;
OnPropertyChanged("Family");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
public string Patronymic
{
get
{
return patronymic;
}
set
{
patronymic = value;
OnPropertyChanged("Patronymic");
}
}
public DateTime BirthDate
{
get
{
return birthDate;
}
set
{
birthDate = value;
OnPropertyChanged("BirthDate");
}
}
public Gender Gender
{
get
{
return gender;
}
set
{
gender = value;
OnPropertyChanged("Gender");
}
}
public int SubdivisionId
{
get
{
return subdivisionId;
}
set
{
subdivisionId = value;
OnPropertyChanged("SubdivisionId");
}
}
}
用戶控制員工視圖
<UserControl x:Class="MerryWaterCarrier.View.EditorWindow.EmployeeEdit"
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:MerryWaterCarrier.View.EditorWindow"
xmlns:vm="clr-namespace:MerryWaterCarrier.ViewModel.EditorWindow"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="1000">
<Grid d:DataContext="{d:DesignInstance vm:EmployeeEditViewModel}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition Width="58.824"/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="20" Foreground="Wheat"
FontSize="40px" TextAlignment="Center">
Id:
</TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" Margin="20">
</TextBox>
<TextBlock Grid.Row="1" Grid.Column="0" Margin="20" Foreground="Wheat"
FontSize="40px" TextAlignment="Center">
Family:
</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Margin="20">
</TextBox>
<TextBlock Grid.Row="2" Grid.Column="0" Margin="20" Foreground="Wheat"
FontSize="40px" TextAlignment="Center">
Name:
</TextBlock>
<TextBox Grid.Row="2" Grid.Column="1" Margin="20">
</TextBox>
<TextBlock Grid.Row="3" Grid.Column="0" Margin="20" Foreground="Wheat"
FontSize="38px" TextAlignment="Center">
Patronymic:
</TextBlock>
<TextBox Grid.Row="3" Grid.Column="1" Margin="20">
</TextBox>
<TextBlock Grid.Row="0" Grid.Column="3" Margin="20" Foreground="Wheat"
FontSize="40px" TextAlignment="Center">
BirthDate:
</TextBlock>
<TextBox Grid.Row="0" Grid.Column="4" Margin="20">
</TextBox>
<TextBlock Grid.Row="1" Grid.Column="3" Margin="20" Foreground="Wheat"
FontSize="40px" TextAlignment="Center">
Gender:
</TextBlock>
<TextBox Grid.Row="1" Grid.Column="4" Margin="20">
</TextBox>
<TextBlock Grid.Row="2" Grid.Column="3" Margin="20" Foreground="Wheat"
FontSize="30px" TextAlignment="Center">
SubdivisionId:
</TextBlock>
<TextBox Grid.Row="2" Grid.Column="4" Margin="20">
</TextBox>
</Grid>
我也有這個問題,經常我不得不在父視圖模型和子視圖模型之間進行通信。 我的第一個解決方案是使用中介模式,但我遇到了很多麻煩,所以我決定將子 ViewModel 保留在父 ViewModel 中,並將父 ViewModel 接口傳遞給子 ViewModel 的構造函數,這對我來說很好用。 注意:僅當父級的 ViewModel 可以訪問子級 ViewModel 時才有效
編輯:正如SoothingMusic在評論中指出的那樣,您也可以向父母訂閱的孩子添加事件,而不是孩子保留父母的參考。
public interface IParent
{
void SelectEmployee(Employee employee);
}
public class ParentViewModel : IParent
{
...
public void SelectEmployee(Employee employee)
{
...
}
}
public class ChildViewModel
{
private readonly IParent _parent;
...
public Employee SelectedEmployee
{
...
set
{
...
_parent.SelectEmployee(value);
}
}
public ChildViewModel(IParent parent)
{
_parent = parent;
}
}
另一種方法
public class ParentViewModel
{
...
public ParentViewModel()
{
...
childViewModel.SelectEmployee += OnEmployeeSelected;
}
public void OnEmployeeSelected(object sender, Employee employee)
{
...
}
}
public class ChildViewModel
{
// You can use any delegate instead of Action
public event Action<object, Employee> SelectEmployee;
...
public Employee SelectedEmployee
{
...
set
{
...
SelectEmployee(this, value);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.