Nano Hash - криптовалюты, майнинг, программирование

Содержимое кадра WPF не обновляется при изменении исходного Uri посредством привязки

Я работаю над этой проблемой в течение нескольких дней и не могу найти ничего, что будет работать для моего приложения.

Моя проблема в том, что я пытаюсь использовать пользовательский элемент управления, содержащий кнопки для привязки к командам, которые изменяют исходный Uri кадра (оба отображаются в одном окне). Когда я нажимаю кнопку, она меняет Uri в ViewModel, но фрейм не меняет страницу, чтобы отразить это. Я считаю, что он либо не улавливает изменения из-за того, как он привязывается, либо что-то блокирует его от изменения страницы, отображаемой в фрейме.

Я использую шаблон MVVM, который был отличным, пока я не дошел до того, что мне пришлось начать заниматься навигацией. Любая помощь будет принята с благодарностью!

Кнопки просмотра навигационных элементов управления:

<Button Name="BtnMainDash" Content="Main Dashboard" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="180" Command="{Binding MainDashboard}"/>
<Button Name="BtnAccount" Content="Account" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top" Width="180" Command="{Binding EditAccount}"/>
<Button Name="BtnProjects" Content="Projects" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top" Width="180" Command="{Binding ProjectScreen}"/>

Рамка главного окна:

<Frame x:Name="FmePages" Margin="200,30,-0.4,0.4"
               Source="{Binding Path=CurrentPage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged }"
               NavigationUIVisibility="Hidden"/>

Кнопка ICommands (все то же самое, за исключением того, что каждая из них вызывает другую команду изменения Uri):

using System;
using System.Windows.Input;
using ScrumManagementApplication.Pages.MainWindow.ViewModel;

namespace ScrumManagementApplication.Pages.MainWindow.Commands
{
    class LoadEditAccount : ICommand
    {
        private readonly NavigationViewModel _navigationViewModel;

        public LoadEditAccount(NavigationViewModel navigationViewModel)
        {
            _navigationViewModel = navigationViewModel;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return _navigationViewModel.CommandsEnabled;
        }

        public void Execute(object parameter)
        {
            _navigationViewModel.LoadEditAccount();
        }
    }
}

Модель представления:

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using ScrumManagementApplication.Pages.MainWindow.Commands;
using ScrumManagementApplication.SessionData;
using MessageBox = System.Windows.MessageBox;

namespace ScrumManagementApplication.Pages.MainWindow.ViewModel
{
    public class NavigationViewModel : INotifyPropertyChanged, INotifyPropertyChanging
    {
        public bool CommandsEnabled = false;

        public NavigationViewModel()
        {
            MainDashboard = new LoadMainDashboard(this);
            EditAccount = new LoadEditAccount(this);
            ProjectScreen = new LoadProjectScreen(this);
            LogOut = new LoadLogOut(this);

            CommandsEnabled = true;

            LoadEditAccount();
        }

        #region ICommands

        public ICommand MainDashboard { get; private set; }
        public void LoadMainDashboard()
        {
            _currentPage = null;
            _currentPage = new Uri("pack://application:,,,/Pages/MainWindow/View/MainDashboardView.xaml", UriKind.Absolute);
        }

        public ICommand EditAccount { get; private set; }
        public void LoadEditAccount()
        {
            _currentPage = null;
            _currentPage = new Uri("pack://application:,,,/Pages/EditUserDetailsPage/View/EditUserDetailsView.xaml", UriKind.Absolute);
        }

        public ICommand ProjectScreen { get; private set; }
        public void LoadProjectScreen()
        {
            _currentPage = null;
            _currentPage = new Uri("pack://application:,,,/Pages/ProjCreationPage/View/ProjectCreationPage.xaml", UriKind.Absolute);
        }

        public ICommand LogOut { get; private set; }
        public void LoadLogOut()
        {
            var dialogResult = MessageBox.Show("Are you sure you want to log out?", "Log Out", MessageBoxButton.YesNo);

            if (dialogResult == (MessageBoxResult) DialogResult.Yes)
            {
                App.Current.Shutdown();
            }
        }

        #endregion // ICommands

        #region MainFrame

        private Uri _currentPage;
        public Uri CurrentPage
        {
            get { return _currentPage; }
            set
            {
                _currentPage = value;
                OnPropertyChanged("CurrentPage");
            }
        }

        #endregion // MainFrame

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion // INotifyPropertyChanged Members

        public event PropertyChangingEventHandler PropertyChanging;

        protected void OnPropertyChanging(String propertyName)
        {
            PropertyChangingEventHandler handler = PropertyChanging;

            if (handler != null)
            {
                handler(this, new PropertyChangingEventArgs(propertyName));
            }
        }
    }
}

Любая помощь приветствуется, даже если она не полностью решает мою проблему, все, что помогает мне приблизиться к решению, хорошо!

заранее спасибо


  • Вы должны создать событие PropertyChanged для системы привязки, чтобы обновить целевое свойство. Вы просто меняете фоновое поле. Вместо этого используйте написанный вами установщик свойств, который автоматически вызывает событие PropertyChanged. 05.12.2014
  • @mikez Привет, Майк, спасибо за помощь. Я думаю, что, возможно, я слишком долго смотрел на свой экран, поскольку я не на 100% то, что вы имеете в виду, можете ли вы уточнить? Спасибо! 05.12.2014
  • Возьмите LoadEditAccount, вы изменяете _currentPage, не вызывая событие изменения свойства для CurrentPage. Вам нужно позвонить OnPropertyChanged("CurrentPage") в какой-то момент после этого. Вы можете просто написать его как CurrentPage = new Uri(...);, что вызовет ваш сеттер и вызовет событие. 05.12.2014
  • @mikez Я пробовал оба этих метода, но он все еще не меняет страницу в фрейме, я добавил в MessageBoxes, чтобы убедиться, что Uri обновляется правильно и в этом нет проблем. По какой-то причине кадр просто не хочет меняться от своего исходного источника. 05.12.2014

Ответы:


1

Вместо того, чтобы делать это

_currentPage = //some value;

сделай это:

CurrentPage = //some value

Событие будет вызвано, когда вы измените свойство, а не поле поддержки.

ИЗМЕНИТЬ

Еще одно предложение — создать единый класс команд, поскольку все ваши команды устанавливают строковое значение для свойства. Вы можете получить имя кнопки, используя функцию CommandParameter. Исходя из этого, установите Uri.

05.12.2014
  • Привет, Пиюш, спасибо за помощь. Я пробовал это, и, похоже, это не сработало, я не думаю, что мог неправильно выполнять ваши инструкции, поскольку они довольно просты, хотя просто чтобы дважды проверить, что мне делать с get; набор; для текущей страницы? Еще раз спасибо! 05.12.2014
  • get и set останутся прежними для CurrentPage. Но вы должны установить значение свойства (CurrentPage) вместо резервного поля (_currentPage) в таких методах, как LoadProjectScreen или LoadEditAccount. 05.12.2014
  • Это тоже не работает, по какой-то причине он, похоже, не обновляет источник, за исключением случаев, когда команда для его установки запускается внутри метода инициализации NavigationViewModel(), после того как он установлен, он больше не меняется. Я не могу придумать для этого никакой причины, так как использую одни и те же команды внутри и снаружи этого метода. 05.12.2014

  • 2

    Получил аналогичную проблему, в нем было главное окно с фреймом, и когда я, например, открыл диалоговое окно openfile и закрыл его, этот фрейм (также некоторые другие) не обновлялся, даже если я вызывал PropertyChanged() и связанное свойство имело правильное значение . Единственным решением для меня было удалить привязку и вместо этого обрабатывать контент с помощью NavigationService. Если вам нужно это свойство, к которому вы привязаны для некоторых других подходов, вы можете сделать что-то вроде:

        private Page _dataExplorerContent;
        public Page DataExplorerContent
        {
            get { return _dataExplorerContent; }
            set
            {
                if(value != null)
                {
                    contentFrame.Navigate(value)
                    SetField(ref _dataExplorerContent, value);
                }
            }
        }
    
    19.08.2017
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..