Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a navigation button in shared application resources?

I'm currently trying to create a simple app that pulls data from an API I made and displays it in a list. You are then supposed to be able to click the list items to be navigated to a detailed view page with an image viewer etc. For that to work I need to navigate to a page called PlanViewer.xaml (currently only available for the Windows Phone app part, will do for both though).

For my list to work I built the following data template in my shared App.xaml:

    <DataTemplate x:Key="PlanDataTemplate">
        <StackPanel Orientation="Horizontal">
            <Button Name="NavigatePlan" Tag="{Binding FilePath}">
                <StackPanel>
                    <TextBlock Style="{StaticResource SubheaderTextBlockStyle}" Text="{Binding Name}" />
                    <TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="{Binding LastUpdate}" />
                </StackPanel>
            </Button>
        </StackPanel>
    </DataTemplate>

I apply it in my MainPage.xaml as shown here:

<ItemsControl x:Name="PlanList" ItemTemplate="{StaticResource PlanDataTemplate}" ItemsSource="{Binding PlanItems}" >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

I can't bind any events to the button in the App.xaml, so I think I need to use an ICommand interface. I might also have a much more fundamental mistake in how I built this thing so far.

TL;DR for my goal: I want to adjust the datatemplate so that every button links to a page PlanViewer.xaml with an argument describing which plan is supposed to be shown (e.g. ID or file path).

like image 359
Heiko Rothe Avatar asked Feb 12 '23 03:02

Heiko Rothe


1 Answers

This is an Universal App solution. It's can view as basically a tutorial on Model, View,and ViewModel.

I don't know what UI Element you want to use, but for this I going to pick a one that is supported in both Windows 8.1 and WP 8.1. The ListView, so in both Project's MainPage.xaml lets define that.


<ListView x:Name="myListView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Artist}"></TextBlock>
                <TextBlock Text="{Binding Song}"></TextBlock>
                <Button Command="{Binding ElementName=myListView, Path=DataContext.SimpleCommand}"
                        CommandParameter="{Binding Extra}"
                        x:Name="mybutton" Width="200" Height="50" FontFamily="Global User Interface" Content="Click Me"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

As you can see, I databinded the Button with a Command and a CommandParameter. The command is the function in the ViewModel that I want to execute when the user clicks the button. The CommandParameter is a object you want to pass to your Command function. In your case, your TAG.


Namespaces

using System.Collections.ObjectModel;              // ObservableCollection
using System.Windows.Input;                        // ICommand

Now lets defined a Command (Should be part of the Shared Project)

public class MySimpleCommand : ICommand
{
    public void Execute(object parameter)
    {
        // do stuff based off your tags
        string tag = parameter as string;
        if(tag == "WHATEVER_YOU_WANT")
        {
        }

        // void of the trigger libraries, lets make this simple
        // navigate to your page
        Frame rootFrame = Window.Current.Content as Frame;
        rootFrame.Navigate(typeof(YOUR_PAGE));

    }
    public bool CanExecute(object parameter)
    {
        return true;
    }
    public event EventHandler CanExecuteChanged;
}

Now lets setup a simple model (Should be part of the Shared Project)

public class sample_model
{
    public sample_model(string artist, string song, string extra = "")
    {
        this.Artist = artist;
        this.Song = song;
        this.Extra = extra;
    }

    public string Artist { get; set; }
    public string Song { get; set; }
    public string Extra { get; set; }         // this is your tag
}

Now lets setup a ViewModel for our ListView(s) to use. (Should be part of the Shared Project)

public class sample_viewmodel
{
    public sample_viewmodel()
    {
        this.DataSource = CreateData();

        this.SimpleCommand = new MySimpleCommand();  // create the command
    }

    // create a static list for our demo
    private ObservableCollection<sample_model> CreateData()
    {
        ObservableCollection<sample_model> my_list = new ObservableCollection<sample_model>();
        my_list.Add(new sample_model("Faith + 1", "Body of Christ", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ Again", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "A Night With the Lord", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Touch Me Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Found Jesus (With Someone Else)", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Savior Self", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ What a Day", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Three Times My Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus Touched Me", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Lord is my Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Wasn't Born Again Yesterday", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Pleasing Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus (Looks Kinda Hot)", "A Track"));
        my_list.Add(new sample_model("Butters", "What What", "B Track"));
        return my_list;            
    }

    public ICommand SimpleCommand { get; set; }
    public ObservableCollection<sample_model> DataSource{ get; set; }

}

And finally, lets link the ListView to our ViewModel which should bind the "Artist, Song, and Button (Command & CommandParamters)". I usually do this in each Page's Load function.

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    sample_viewmodel viewmodel = new sample_viewmodel();  // create the view model
    myListView.DataContext = viewmodel;                   // set the datacontext (this will link the commands)
    myListView.ItemsSource = viewmodel.DataSource;        // set the ItemsSource, this will link the Artist,Songs
}

There you have it, each time the user clicks on the button no matter what platform it will perform the Command function.


Sample Screenshot enter image description here

like image 200
Chubosaurus Software Avatar answered Feb 15 '23 08:02

Chubosaurus Software