I need to show items in dropdown menu in line. How can i make it?
You will probably need to build the Control yourself. You can make a Composite Control consisting of a <Button> and a <ListBox> to emulate what you're trying to do. It is actually pretty easy.
For example:
<Button Content="{Binding SelectedItem.Song, FallbackValue=Show List, ElementName=myListBox}" Height="100" Click="Button_Click"></Button>
<ListBox x:Name="myListBox" Height="60" Visibility="Collapsed">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="1" Height="50" Padding="15,0">
<TextBlock VerticalAlignment="Center">
<Run Text="{Binding Song}"></Run>
</TextBlock>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What I did here is programmed a Button with its Content Binded to the ListBox's SelectedItem which has .Song Property, if none is selected it falls back to "Show List"
When the user clicks on the button it should hide/show the list box depending on its current Visibility.
private void Button_Click(object sender, RoutedEventArgs e)
{
if (this.myListBox.Visibility == System.Windows.Visibility.Collapsed)
{
this.myListBox.Visibility = System.Windows.Visibility.Visible;
}
else
this.myListBox.Visibility = System.Windows.Visibility.Collapsed;
}
Your job is to wrap all this up inside a nice UserControl or you can just use it as is.
Here are some screenshots of it in action:
Related
How to pass CommandParameter on holed item?
my xaml code
<ListView Grid.Row="1" Name="ProfilesListView" SelectedItem="{Binding SelectedUser,Mode=TwoWay}" ItemsSource="{Binding Path=ViewAllProfile,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" HorizontalAlignment="Center">
</ItemsWrapGrid>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<I:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Holding">
<core:InvokeCommandAction Command="{Binding Path=HoldingCommand}" CommandParameter="{Binding ElementName=ProfilesListView,Path=SelectedItem}" ></core:InvokeCommandAction>
</core:EventTriggerBehavior>
</I:Interaction.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0,0,0">
<Image Margin="10" Source="{Binding ImageURL}" Width="150" Height="150" >
</Image>
<TextBlock x:Name="userName" Text="{Binding MenuName}" Foreground="White" HorizontalAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
my viewmodel is .i am not getting the holding item details .how to solve this
_HoldingCommand = new RelayCommand<object>(HoldedUser);
Not sure this can be done directly through MVVM binding.
The holding event won't set the selected item straight away...
If you would register to the holding event and use code behind, you'll notice the 'holded' item is only known in the HoldingRoutedEventArgs - something like this:
private async void OnListViewHolding(object sender, HoldingRoutedEventArgs e)
{
var selectedItemThroughHolding = e.OriginalSource.DataContext as ***Model;
}
So my suggestion would be to use this code behind event and reroute the selectedItem to the viewmodel there...
I have a windows 8.1 store app and I can't figure out how to get the datacontext to access my viewmodel for a relaycommand. The xaml works all the way up to the flyout and then it fails. So the button with content "buttonWorks" successfully gets the binding from the rootGrid element and calls the command on the viewmodel. But the button right below in the flyout does not. Why?
To make an example of the binding problem, create a new Store App with the Split App template. Then add a flyout to the SplitPage and bind a textbox text to the itemtitle element. The binding will not populate the flyout textbox. The code snippet looks like this:
<Image Source="{Binding ImagePath}" Grid.Row="1" Margin="0,0,20,0" Width="180" Height="180" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
<StackPanel x:Name="itemDetailTitlePanel" Grid.Row="1" Grid.Column="1">
<TextBlock x:Name="itemTitle" Margin="0,-10,0,0" Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}"/>
<TextBlock x:Name="itemSubtitle" Margin="0,0,0,20" Text="{Binding Subtitle}" Style="{StaticResource SubtitleTextBlockStyle}"/>
<Button Content="Update">
<Button.Flyout>
<Flyout>
<StackPanel>
<StackPanel Margin="5" Orientation="Vertical" >
<TextBlock Text="Item Title" VerticalAlignment="Bottom"/>
<TextBox Text="{Binding ElementName=itemTitle,Path=Text,Mode=TwoWay}" Width="200" />
</StackPanel>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
I can get the command binding to work using Dani's answer and setting the datacontext on the button hosting the flyout like this, but I can't bind the textboxes as seen in the template example above
<Button Content="Update" HorizontalAlignment="Center" DataContext="{Binding ViewModel, ElementName=pageRoot}" >
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock Text="Item Title" VerticalAlignment="Bottom"/>
<TextBox Text="{Binding ElementName=itemTitle,Path=Text,Mode=TwoWay}" Width="200" />
<Button x:Name="buttonTest" Margin="5" Height="40" Content="Test" HorizontalAlignment="Center" Command="{Binding UpdateMatchDataCommand}"/>
Original Code Example Problem:
<Grid Name="rootGrid" Tag="{Binding}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
....
<ScrollViewer
x:Name="itemDetail"
AutomationProperties.AutomationId="ItemDetailScrollViewer"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
Padding="60,0,66,0"
HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"
DataContext="{Binding SelectedItem, ElementName=itemListView}"
<Grid x:Name="itemDetailGrid" Margin="0,60,0,50">
<StackPanel Orientation="Vertical" Grid.Row="1" Margin="0,0,10,0" Width="180" Height="180">
<Button Name="buttonWorks" Content="Test" Command="{Binding Tag.UpdateMatchDataCommand,ElementName=rootGrid}"/>
<Button Content="Update" HorizontalAlignment="Center" >
<Button.Flyout>
<Flyout>
<Button Name="buttonFail" Content="Test" Command="{Binding Tag.UpdateMatchDataCommand,ElementName=rootGrid}"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
....
If you work with ViewModels I would suggest that you change the DataContext to your page.
<Page
x:Name="rootPage"
DataContext="{Binding ViewModel, RelativeSource={RelativeSource Self}}"
...
And CodeBehind:
private readonly ViewModel _viewModel = new ViewModel();
public ViewModel ViewModel
{
get { return _viewModel; }
}
Now you can change your commands to:
<Button Name="buttonWorks" Content="Test" Command="{Binding Tag.UpdateMatchDataCommand}"/>
ElementName is now only necessary if you bind to a property in code behind.
It ends up that I could never solve the problem using the binding that the template provides. It appears to me that changing the datacontext of a single element in the flyout is not allowed. So, the way I got around it is to create a selected item in the viewmodel and changed the template code to bind to the selected item on view model. Then bind all elements including the command to the same datacontext for the entire form.
<ListView
x:Name="itemListView"
AutomationProperties.AutomationId="ItemsListView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.Row="1"
Margin="-10,-10,0,0"
Padding="120,0,0,60"
ItemsSource="{Binding Matches}"
SelectedItem="{Binding SelectedMatch, Mode=TwoWay}"
IsSwipeEnabled="False">
<ListView.ItemTemplate>
<DataTemplate>
Now the binding works for all fields including the template.
He everybody!
What I want to do is to open a flyout with list of items (binded to a collection from a ViewModel) and then, when a user chooses any item in the list, the flyout should be hidden. To achieve this I'm using a behavior which hides the flyout. The problem is that the behavior doesn't work when I'm tapping on the item that is already chosen (on currently selected item).
I have the following code.
<Button.Flyout>
<Flyout Placement="Full">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding SelectedCategory}"
ComparisonCondition="NotEqual">
<controls:CloseFlyoutAction />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ListView ItemsSource="{Binding Source={StaticResource GroupedCategories}}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}">
<ListView.GroupStyle>
<GroupStyle>
//... skiped for brevity
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Foreground="{Binding IsSelected, Converter={StaticResource ForegroundConverter}}"
Content="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Flyout>
</Button.Flyout>
I want to open a ListPicker in Fullscreen mode on ApplicationBarButton click. The ListPicker should be opened as new popup and should not be visible in the page.
This was my try:
private void OnAppBarButtonClick(object sender, EventArgs e)
{
ListPicker listPicker = new ListPicker();
listPicker.ExpansionMode = ExpansionMode.FullScreenOnly;
this.ContentPanel.Children.Add(listPicker);
ListPickerItem item1 = new ListPickerItem() { Content = "Item1" };
ListPickerItem item2 = new ListPickerItem() { Content = "Item2" };
ListPickerItem item3 = new ListPickerItem() { Content = "Item3" };
listPicker.Items.Add(item1);
listPicker.Items.Add(item2);
listPicker.Items.Add(item3);
listPicker.Open();
}
You can accomplish this by defining the ListPicker in your xaml, setting the ExpansionMode to FullScreenOnly and making it Collapsed.
<Grid x:Name="Content"/>
<!-- other controls -->
<toolkit:ListPicker x:Name="Picker" ExpansionMode="FullScreenOnly"
Visibility="Collapsed"
FullModeHeader="SELECT"
ItemsSource="{Binding MyItems}"
SelectionChanged="OnPickerSelectionChanged">
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<TextBlock Margin="0,20" Text="{Binding Name}"/>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
</Grid>
Then in your code, you open the picker.
Picker.Open();
This samples assumes you have a DataContext with a MyItems property that is a collection of items that has a Name property.
this code works for me without the need of any base code,
<toolkit:ListPicker Header="State"
x:Name="State"
ExpansionMode="FullScreenOnly">
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
Margin="0 24 24 24"
TextWrapping="Wrap"
Style="{StaticResource PhoneTextTitle2Style}" />
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
Just initialize State.ItemsSource with a list.
I have a LongListSelector like that
<phone:LongListSelector Name="ListRecentFiles"
LayoutMode="Grid"
ItemsSource="{Binding}"
GridCellSize="140,140"
SelectionChanged="ListRecentFiles_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Background="Red" Margin="0,0,5,5">
<TextBlock Text="{Binding NoteTitle}" Style="{Binding PhoneTextNormalStyle}" />
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="ContextMenu">
<toolkit:MenuItem x:Name="Delete" Header="Delete" Click="DeleteNote_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
this is DataContext: public static ObservableCollection<Note> NoteItems;
And i try to delete an item from LongListSelector
private void DeleteNote_Click(object sender, RoutedEventArgs e)
{
Note selectedNote = (sender as MenuItem).DataContext as Note;
ListRecentFiles.ItemsSource.Remove(item);
NoteItems.Remove(selectedNote);
}
It's not work except i navigate to a other XAML page and return
I have visited this page but can't fix link
Without seeing more of the code, it's hard to be sure what's going wrong. But if you are setting
ListRecentFiles.DataContext = NoteItems;
that is incorrect. You want to set
ListRecentFiles.ItemsSource = NoteItems;
The XAML declaration:
ItemSource="{Binding}"
Could do that (depending on the rest of the code). Once .ItemsSource is set correctly, then the line:
NoteItems.Remove(selectedNote);
Should succeed in removing the visual item from the LongListSelector. In any case, you should not do the line:
ListRecentFiles.ItemsSource.Remove(item);
That would do the wrong thing when the list gets so big that it doesn't all fit in memory at once.