Как обновить свойство Source фрейма, нажав только одну кнопку из пользовательского элемента управления? - PullRequest
2 голосов
/ 24 мая 2011

Я хотел бы узнать о том, как обновить исходное свойство, нажав только одну кнопку «Далее» на основе количества кликов и имея возможность загружать разные страницы во фрейм при каждом нажатии кнопки в другой раз.Любой совет высоко ценится!Заранее благодарим.

Код главного окна:

<Grid x:Name="LayoutRoot">
    <Frame Content="Frame" Source="/WpfApplication1;component/Page1.xaml"/>
    <local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Grid>

Элемент управления пользователя, содержащий кнопку:

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">
    <Button Content="Back" HorizontalAlignment="Left" Width="75"/>
    <Button Content="Next" HorizontalAlignment="Left" Width="75" />
</StackPanel>

Ответы [ 2 ]

2 голосов
/ 25 мая 2011

Создайте класс PageViewModel, который реализует команды NextPageCommand и PreviousPageCommand, которые вызывают (соответственно) UserNavigatedToNextPage и UserNavigatedToPreviousPage события.Чтобы упростить задачу, также предложите им выставить свойства NextPage и PreviousPage типа PageViewModel.Создайте подклассы PageViewModel для каждой страницы.

Создайте класс модели представления для владельца UserControl, который предоставляет свойство CurrentPage типа PageViewModel.Создайте все объекты PageViewModel и установите NextPage и PreviousPage для каждого.Добавьте обработчики для событий навигации для этих объектов, которые выглядят примерно так:

public void Page_UserNavigatedToNextPage(object sender, EventArgs e)
{
   if (sender == CurrentPage && CurrentPage.NextPage != null)
   {
      CurrentPage = CurrentPage.NextPage;
   }
}

Предполагая, что вы реализовали уведомление об изменении свойства, теперь, когда выполняется текущая страница NextPageCommand или PreviousPageCommand, *Свойство 1023 * будет обновлено и будет отражено в пользовательском интерфейсе.Если вы создали шаблон данных для каждого типа модели представления страницы, все, что вам нужно, это

<ContentPresenter Content="{Binding CurrentPage}"/>

в вашем пользовательском элементе управления, и вы готовы пойти.

Если следующий /Предыдущие кнопки находятся в вашем элементе управления, а не на странице, затем реализуйте свойства в модели основного вида, которые предоставляют CurrentPage.NextPageCommand и CurrentPage.PreviousPageCommand, и привязывайте кнопки к ним.

1 голос
/ 24 мая 2011

В вашем NavUserControl я бы связывал либо события, либо команды (или оба, возможно) для кнопок «Вперед» и «Назад». Затем вы можете получить доступ к ним из MainWindow и установить соответствующее значение в свойстве Source.

Если вы идете по маршруту события, присоединитесь к событиям и установите источник напрямую.

Если вы идете по маршруту команды, настройте команду в вашей модели представления, привяжите ее к пользовательскому контролю и привяжите свойство Source к другому значению в вашей модели представления.

Редактировать: Добавление некоторого кода по запросу ОП. Имейте в виду, это не является наилучшей практикой. Просто несколько примеров.

Для прохождения события событие должно быть самым простым. Вы уже знаете, как это сделать, я думаю. Просто добавьте:

public event EventHandler BackClicked;
public event EventHandler NextClicked;

private void Back_Click(object sender, RoutedEventArgs e)
{
    BackClicked(sender, e);
}

private void Next_Click(object sender, RoutedEventArgs e)
{
    NextClicked(sender, e);
}

событий на ваш NavUserControl. Затем измените свой XAML на:

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">    
    <Button Content="Back" HorizontalAlignment="Left" Width="75" Click="Back_Click" />    
    <Button Content="Next" HorizontalAlignment="Left" Width="75" Click="Next_Click" />
</StackPanel>

А теперь в вашем файле MainWindow.xaml.cs добавьте:

private void BackClicked(object sender, EventArgs e)
{
    Uri source = // Whatever your business logic is to determine the previous page;
    _Frame.Source = source;
}

private void NextClicked(object sender, EventArgs e)
{
    Uri source = // Whatever your business logic is to determine the next page;
    _Frame.Source = source;
}

и измените XAML MainWindow на:

<Grid x:Name="LayoutRoot">
    <Frame x:Name="_Frame" Content="Frame" 
           Source="/WpfApplication1;component/Page1.xaml"/>
    <local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom" 
                          BackClicked="BackClicked" NextClicked="NextClicked" />
</Grid>

Переход по командному маршруту требует немного больше архитектуры, но намного более чист. Я бы порекомендовал использовать ваш любимый инструментарий MVVM. Мой любимый MVVMLight , поэтому я буду использовать его в этом примере.

Создайте класс ViewModel, примерно так:

public class ViewModel : GalaSoft.MvvmLight.ViewModelBase
{
    private Uri _Source;
    public Uri Source
    {
        get { return _Source; }
        set
        {
            if (_Source != value)
            {
                _Source = value;
                RaisePropertyChanged("Source");
            }
        }
    }



    private GalaSoft.MvvmLight.Command.RelayCommand _BackCommand;
    public ICommand BackCommand
    {
        get
        {
            if (_BackCommand == null)
            {
                _BackCommand = new GalaSoft.MvvmLight.Command.RelayCommand(() =>
                {
                    Uri source = // Whatever your business logic is to determine the previous page
                    Source = source;
                });
            }
            return _BackCommand;
        }
    }

    private GalaSoft.MvvmLight.Command.RelayCommand _NextCommand;
    public ICommand NextCommand
    {
        get
        {
            if (_NextCommand == null)
            {
                _NextCommand = new GalaSoft.MvvmLight.Command.RelayCommand(() =>
                {
                    Uri source = // Whatever your business logic is to determine the next page
                    Source = source;
                });
            }
            return _NextCommand;
        }
    }
}

В вашем MainWindow.xaml.cs создайте экземпляр этого класса и присвойте свойству DataContext этот экземпляр. Затем настройте привязки:

<Grid x:Name="LayoutRoot">    
    <Frame Content="Frame" Source="{Binding Source}"/>    
    <local:NavUserControl HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Grid>

и

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20">    
    <Button Content="Back" HorizontalAlignment="Left" Width="75" Command="{Binding BackCommand}"/>    
    <Button Content="Next" HorizontalAlignment="Left" Width="75" Command="{Binding NextCommand}" />
</StackPanel>

Пример привязки - довольно простой WPF в стиле MVVM. Я бы посоветовал вам пойти по этому пути, и если вам нужна дополнительная помощь, прочитайте статью о MVVM в WPF. Много ресурсов там в виде учебников и книг. Поиск здесь по SO также может помочь.

Изменить еще раз:

Измените свой конструктор на это:

public MainWindow()
{
    this.InitializeComponent();

    // Insert code required on object creation below this point.
    DataContext = new ViewModel();
}
...