Otwarcie nowego okna dialogowego z poziomu ViewModelu

0

Chciałbym w momencie zmiany wartości właściwości int OperTechnologicznaVM.NrOperacji wyświetlić okno dialogowe informujące użytkownika ze nastąpiła zmiana, ta zmiana jest powiązana z czymś tam i czy to cos tamto ma również się zmienić , wymagane odpowiedzi z okna dialogowego OK, lub Anuluj i w zaleznosci od wyboru w ViewModelu zrobiłbym sobie jakąś akcje.
Ale uwaga, w treści okna dialogowego chciałbym tez odpowiednio przygotować opis wynikający z zakresu powiązanych zmian.

Jak wywołać takie okno dialogowe z poziomu ViewModelu?

Fragment mojego widoku ponizej.
Do pierwszego TextBoxa jest zbindowana wlasciwosc NrOperacji na zmianę której chce reagować oknem dialogowym:

<ListBox DockPanel.Dock="Top" 
                                         ItemsSource="{Binding WszystkieMarszrutyArtykuluZGlownej}">
                                    <ListBox.ItemTemplate>
                                        <DataTemplate>
                                            <StackPanel Orientation="Vertical">
                                                <StackPanel Orientation="Horizontal">
                                                    <TextBlock Text="Mar.:" FontSize="14" Margin="3,0,2,0"/>
                                                    <TextBlock Text="{Binding NrMarszruty}" FontSize="14" FontWeight="Bold" Width="20"/>
                                                    <TextBlock Text="Artykuł:" FontSize="14" Margin="3,0,2,0"/>
                                                    <TextBlock Text="{Binding Index}" Margin="1,0,0,0" FontSize="14" FontWeight="Bold"/>
                                                </StackPanel>
                                                <ListBox ItemsSource="{Binding OperacjeEdytowane}">
                                                    <ListBox.ItemTemplate>
                                                        <DataTemplate>
                                                            <StackPanel Orientation="Vertical" Margin="0">
                                                                <DockPanel>
                                                                    <TextBox DockPanel.Dock="Left" Text="{Binding NrOperacji}" Margin="0,1,3,0" Width="25" FontWeight="SemiBold"
                                                                         TextAlignment="Right" FontFamily="Segoe UI Symbol" IsEnabled="True" VerticalContentAlignment="Center"/>
                                                                    <TextBlock DockPanel.Dock="Left" Text="{Binding KodStanowiska}" Width="65" FontWeight="Normal" 
                                                                            TextAlignment="Left" FontFamily="Segoe UI Semibold" Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Right">
                                                                        <TextBlock Text="Kod Oper."  Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                        <TextBox Text="{Binding KodOperatora}" Margin="0,1,3,0" Width="30" IsEnabled="False" FontWeight="SemiBold"
                                                                                  VerticalContentAlignment="Center" TextAlignment="Center"/>
                                                                    </StackPanel>
                                                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Right">
                                                                        <TextBlock Text="Ilosc stan." Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                        <nud:DecimalUpDown Margin="0,1,3,0" ShowButtonSpinner="True" Increment="0.1" TextAlignment="Right" CultureInfo="pl-PL"
                                                                                    Value="{Binding IloscStanowisk}" Width="40" IsEnabled="True" FontWeight="SemiBold" FormatString="F1"/>
                                                                    </StackPanel>
                                                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Right">
                                                                        <TextBlock Text="Tn:"  Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                        <nud:TimeSpanUpDown Margin="0,1,3,0" ShowDays="True" ShowButtonSpinner="False" 
                                                                                    Value="{Binding Czas_Tn.CzasStandard}"  Width="70" FontWeight="SemiBold"
                                                                                    IsEnabled="True" TextAlignment="Right" CultureInfo="pl-PL"/>
                                                                    </StackPanel>
                                                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Right">
                                                                        <TextBlock Text="Tr:" Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                        <nud:TimeSpanUpDown Margin="0,1,3,0" ShowDays="False" ShowButtonSpinner="False"
                                                                                    Value="{Binding Czas_Tr.CzasStandard}"  Width="55"  FontWeight="SemiBold"
                                                                                    IsEnabled="True" TextAlignment="Right" CultureInfo="pl-PL"/>
                                                                    </StackPanel>
                                                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Right">
                                                                        <TextBlock Text="Tpz:" Margin="0,1,3,0" VerticalAlignment="Center"/>
                                                                        <nud:TimeSpanUpDown Margin="0,1,3,0" ShowDays="False" ShowButtonSpinner="False"  
                                                                                    Value="{Binding Czas_Tpz.CzasStandard}"   Width="55" FontWeight="SemiBold"
                                                                                    IsEnabled="True" TextAlignment="Right" CultureInfo="pl-PL"/>
                                                                    </StackPanel>
                                                                    <TextBox Text="{Binding OpisOperacji}" Width="170" IsEnabled="True"
                                                                            Margin="0,1,3,0" FontFamily="Segoe UI Symbol" VerticalContentAlignment="Center"/>
                                                                    <StackPanel DockPanel.Dock="Right"></StackPanel>
                                                                </DockPanel>
                                                            </StackPanel>
                                                        </DataTemplate>
                                                    </ListBox.ItemTemplate>
                                                </ListBox>

                                            </StackPanel>
                                        </DataTemplate>
                                    </ListBox.ItemTemplate>
                                </ListBox>

Zrodlem danych do tego ListBox'a jest kolekcja:

public ObservableCollection<MarszrutaVM> WszystkieMarszrutyArtykuluZGlownej

a w definicji MarszrutaVM mam taką kolekcję:

public ObservableCollection<OperTechnologicznaVM> OperacjeEdytowane

a definicja OperTechnologicznaVM wyglada tak:

    public class OperTechnologicznaVM : ViewModelBase
    {
        public event ZmianaNrOperacjiEventHandler OnZmianaNrOperacji;

        private OperacjaTechnologiczna modelOperacjaOryginalna;
        private OperacjaTechnologiczna modelOperacjaEdytowalna;
        private bool czyZmieniony;

//(...)

        public int NrOperacji
        {
            get { return modelOperacjaEdytowalna.NrOperacji; }
            set
            {
                int arch = NrOperacji;
                
                OnZmianaNrOperacji?.Invoke(this.modelOperacjaEdytowalna, new ZmianaNrOperacjiEventArgs(arch, value, this.Index, this.AltNrMarszruty));

                CzyZmieniony = modelOperacjaOryginalna != modelOperacjaEdytowalna;
                OnPropertyChanged(nameof(NrOperacji));
            }
        }
   }
0

Kliknij PPM na projekt -> Nowe okno - Tworzymy okno dialogu, czyli własny Widok, własny ViewModel i własny Model. Ja troszkę ukróciłem kod (nie mam viewModelu)
Następnie tworzymy DependencyProperty i Event

public partial class Dialog : Window
    {
        public Dialog()
        {
            InitializeComponent();
        }



        public string Description
        {
            get { return (string)GetValue(DescriptionProperty); }
            set { SetValue(DescriptionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Description.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DescriptionProperty =
            DependencyProperty.Register("Description", typeof(string), typeof(Dialog), new PropertyMetadata(""));

        private void hOK_Click(object sender, RoutedEventArgs e)
        {
            OkButtonClicked?.Invoke(this, EventArgs.Empty);
        }
        public event EventHandler<EventArgs> OkButtonClicked;
    }
<Window x:Class="WpfApp2.Dialog"
        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:WpfApp2"
        mc:Ignorable="d"
        Title="{Binding ElementName=hDialog, Path=Title}" Height="auto" Width="auto"
        x:Name="hDialog">
    <StackPanel>
        <Label Content="{Binding ElementName=hDialog, Path=Description}"/>
        <WrapPanel>
            <Button x:Name="hOK" Click="hOK_Click">Ok</Button>
        </WrapPanel>
    </StackPanel>
</Window>

Skoro widok i logikę dialogu mamy za sobą możemy go utworzyć:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            dialog = new Dialog();
            dialog.OkButtonClicked += Dialog_OkButtonClicked;
            
        }

        private void RequestOpenDialog(string title, string description)
        {
            dialog.Title = title;
            dialog.Description = description;
            dialog.ShowDialog();
        }
        private void Dialog_OkButtonClicked(object? sender, EventArgs e)
        {
            dialog.Close();
        }

        private Dialog dialog { get; set; }
    }

Instancję dialogu bez przeszkód możesz przenieść sobie do swojego ViewModelu

1 użytkowników online, w tym zalogowanych: 0, gości: 1