MVVM - доступ к элементу xaml в представлении из ViewModel - PullRequest
0 голосов
/ 07 мая 2018

Модели:

  • TabModel.cs

  • DisplayTabViewModel.cs - содержит несколько перезаписанных свойств из TabModel, таких как имя, заголовок и т. Д.

ViewModels:

  • MainViewModel.cs

Просмотров: 1024 * *

  • MainWindow.xaml - Окно

  • DisplayTabView.xaml - Контроль пользователя


Это чистый шаблон MVVM, без кода. TabModel вызывает EventHandler - RefreshRequested после закрытия документа Word. MainViewModel содержит подписчика. Метод Refresh () in MainViewModel работает нормально. Метод срабатывает после закрытия документа. Теперь я хотел бы обновить WebBrowser в DisplayTabView.xaml из MainViewModel . Я борюсь с этим уже слишком много часов. Не могли бы вы указать мне в правильном направлении. Спасибо.


TabModel.cs

public abstract class TabModel : ITabModel, INotifyPropertyChanged
{
    public async void HiddenFileExists()
    {
        (...)

        OnRefreshRequested();
    }

    public delegate void RefreshRequestedEventHandler(object source, EventArgs args);

    public event RefreshRequestedEventHandler RefreshRequested;

    public virtual void OnRefreshRequested()
    {
        RefreshRequested?.Invoke(this, EventArgs.Empty);
    }
}

MainViewModel.cs

public class MainViewModel : INotifyPropertyChanged
{
    private readonly ObservableCollection<ITabModel> tabs;

    private void DisplayFileTab(object parameter)
    {
        (...)

        tabs.ElementAt(TabIndex).RefreshRequested += Refresh;
    }

    public void Refresh(object source, EventArgs args)
    {
        MessageBox.Show("Refresh");
    }

DisplayTabView.xaml

<Grid>
    <WebBrowser h:WebBrowserExtensions.BindableSource="{Binding FileUrl}" Tag="{Binding AcceptedKeywordsArray}" h:WebBrowserExtensions.BindableLoaded="{Binding}" />
</Grid>

MainWindow.xaml

<Grid>
    <DockPanel>
        <TabControl Name="tabControl" ItemsSource="{Binding Tabs}" SelectedIndex="{Binding TabIndex}">
            <TabControl.Resources>
                <DataTemplate DataType="{x:Type m:DisplayTabViewModel}">
                    <v:DisplayTabView x:Name="DisplayTab"/>
                </DataTemplate>
            </TabControl.Resources>
            <TabControl.ItemTemplate>
                <DataTemplate DataType="{x:Type m:ITabModel}">
                    <Grid>
                        (...)
                    </Grid>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>
    </DockPanel>
</Grid>

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

MainViewModel может использовать средство создания событий или мессенджер для отправки события / сообщения, на которое может подписаться любой другой компонент, например, другая модель представления или представление в вашем приложении.

Путем введения агрегатора событий или мессенджера между издателями и подписчиками вы устраняете тесную связь между издателем и потребителем события. И издатель, и потребитель знают только о агрегаторе событий, но они ничего не знают и не имеют никаких ссылок друг на друга. Пожалуйста, обратитесь к следующим ссылкам для получения дополнительной информации о концепции.

Использование шаблона агрегатора событий для связи между моделями представления: https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

MVVM - Службы Messenger и View в MVVM: https://msdn.microsoft.com/en-us/magazine/jj694937.aspx

Большинство библиотек MVVM имеют свою собственную реализацию такого рода вещей. В Prism это называется EventAggreator. И в MvvmLight это называется Messenger.

Вот несколько примеров кода о том, как их использовать:

https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/14-UsingEventAggregator

https://marcominerva.wordpress.com/2014/06/25/how-to-send-string-and-content-messages-with-mvvm-light-messenger/

Конечно, вы можете также реализовать свой собственный агрегатор событий, если хотите.

0 голосов
/ 07 мая 2018

Практически во всех средах MVVM реализована шина сообщений, которую вы можете использовать для отправки сообщений между моделями представления, в вашем случае из MainViewModel в DisplayTabViewModel.

Если вы по какой-то причине против использования инфраструктуры MVVM, вам придется реализовать собственную шину сообщений, которая не будет иметь особого смысла, поскольку существует так много великолепных инфраструктур MVVM ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...