Reputation: 2790
I'm trying to implement a SplitView Menue with the Hamburger Button on the bottom. In the Designer powered by VisualStudio it is looking like this:
The xaml code is that:
<Page.Resources>
<ValueConverters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<vm:ShellViewModel x:Key="ShellVM"/>
</Page.Resources>
<Page.DataContext>
<Binding Source="{StaticResource ShellVM}"/>
</Page.DataContext>
<Grid Background="Transparent">
<SplitView x:Name="SplitView" IsPaneOpen="True" PaneBackground="Gray" Content="{Binding}" DisplayMode="Inline" VerticalAlignment="Bottom" Margin="0,0,0,40" Width="200" HorizontalAlignment="Left">
<SplitView.Pane>
<ListView ItemsSource="{Binding MenueButtons}" Height="Auto">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="Auto">
<Grid Width="8" Background="Yellow" HorizontalAlignment="Left" Height="20" Margin="-15,4,0,0" Visibility="{Binding Highlighted, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<RadioButton FontFamily="Segoe MDL2 Assets" Style="{StaticResource TextBlockButtonStyle}" Content="{Binding SymbolIndex}" Margin="-10,0,14,0"/>
<TextBlock Text="{Binding Description}" Margin="-10,5,4,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</SplitView.Pane>
</SplitView>
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="40" Foreground="White" FontSize="20"
Width="50" Background="Green"/>
</Grid>
As you can see I'm Binding the ListView Items to an ObservableCollection of type MenueButtons.
Now I'm trying to nest the Frame in the SplitView Content in App.xaml.cs like this:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
var shell = Window.Current.Content as Shell;
rootFrame = null;
if (shell == null)
{
shell = new Shell();
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
}
}
shell.DataContext = rootFrame;
Window.Current.Content = shell;
}
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
The code behind Shell.xaml.cs is empty because I'm using the MVVM pattern. But here is the code from the ShellViewModel:
public class ShellViewModel:INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
private ObservableCollection<Models.SplitView.MenueButton> _menueButtons;
public ObservableCollection<Models.SplitView.MenueButton> MenueButtons
{
get { return _menueButtons; }
set { _menueButtons = value; OnPropertyChanged("MenueButtons"); }
}
#endregion INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public ShellViewModel()
{
MenueButtons = new ObservableCollection<Models.SplitView.MenueButton>();
MenueButtons.Add(new Models.SplitView.MenueButton { Description = "Statistic", SymbolIndex = "\uEA40" });
MenueButtons.Add(new Models.SplitView.MenueButton { Description = "Settings", SymbolIndex = "\uE713" });
MenueButtons.Add(new Models.SplitView.MenueButton { Description = "Home", SymbolIndex = " \uE80F", Highlighted = true });
}
}
Now to the Issues I'm having:
The binding error:
Error: BindingExpression path error: 'MenueButtons' property not found on 'Windows.UI.Xaml.Controls.Frame'. BindingExpression: Path='MenueButtons' DataItem='Windows.UI.Xaml.Controls.Frame'; target element is 'Windows.UI.Xaml.Controls.ListView' (Name='null'); target property is 'ItemsSource' (type 'Object')
And I think because the SplitView is so small the nested frame won't use the whole screen width and height.
Further Information: The ShellViewModel.cs is containing the ObservableCollection. After launching the App I can only see the green hamburger menue button.
How can I fix this errors?
Upvotes: 0
Views: 439
Reputation: 4239
There were two problems in your code.
1) Binding of Splitview Content
2) Defined Splitview Width
Now for first major problem you are using ShellViewModel
as the dataContext for binding but inside your App.xaml
you are initializing datacontext to null frame of rootFrame. The workaround fix would be keeping binding to ShellViewmodel
and passing frames.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
var shell = Window.Current.Content as Shell;
if (rootFrame == null)
{
rootFrame = null;
if (shell == null)
{
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
}
}
//shell.NewFrame = rootFrame;
shell = new Shell(rootFrame);
Window.Current.Content = shell;
}
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
And shell code behind would become
public Shell(Frame frame)
{
this.InitializeComponent();
SplitViewNew.Content = frame; //this is SplitviewName
}
Now Width="200"
defines complete Splitview width frame and overlay. I am guessing you intended to use OpenPaneLength="200"
Shell view
<Page.DataContext>
<vm:ShellViewModel/>
</Page.DataContext>
<Grid Background="Transparent">
<SplitView x:Name="SplitViewNew" IsPaneOpen="True" PaneBackground="Gray" DisplayMode="Inline" VerticalAlignment="Bottom" Margin="0,0,0,40" HorizontalAlignment="Left">
<SplitView.Pane>
<Grid>
<ListView ItemsSource="{Binding MenueButtons}" Height="Auto">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="Auto">
<Grid Width="8" Background="Yellow" HorizontalAlignment="Left" Height="20" Margin="-15,4,0,0" />
<RadioButton FontFamily="Segoe MDL2 Assets" Style="{StaticResource TextBlockButtonStyle}" Content="{Binding SymbolIndex}" Margin="-10,0,14,0"/>
<TextBlock Text="{Binding Description}" Foreground="White" Margin="-10,5,4,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</SplitView.Pane>
</SplitView>
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="40" Foreground="White" FontSize="20"
Width="50" Background="Green"/>
</Grid>
</Page>
I am uploading Workable Sample so that its easier to see it in working condition. You can now easily make changes if you want to remove code behind completely.
Upvotes: 1