簡體   English   中英

C# WPF 我如何將數據從用戶控制傳遞到主 VM

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM