I have been having a problem with getting the exact value from the stackpanel.
XAML
<Page
x:Class="MedicinesApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MedicinesApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="MedicinesCollectionViewSource" IsSourceGrouped="True" />
</Page.Resources>
<GridView
ItemsSource="{Binding Source={StaticResource MedicinesCollectionViewSource}}"
x:Name="MedicinesGridView"
Padding="30,20,40,0"
SelectionMode="Single"
IsSwipeEnabled="false"
IsItemClickEnabled="True" SelectionChanged="MedicinesGridView_SelectionChanged"
ItemClick="MedicinesGridView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate x:Name="templateTrending">
<Grid HorizontalAlignment="Left" Width="250" Height="250" x:Name="wow">
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Path=DiseaseImageSource}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<StackPanel Orientation="Vertical">
<TextBlock Text="Disease Name" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="30" Margin="15,0,15,0"/>
<TextBlock x:Name="DiseaseNameBro" Text="{Binding Path=DiseaseName, Mode=TwoWay}" Style="{StaticResource TitleTextBlockStyle}" Height="30" Margin="15,0,15,0"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock Text="Category of Disease" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,87,10"/>
<TextBlock Text="{Binding Path=CategoryOfDisease}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text='{Binding Key}' Foreground="Gray" Margin="5" FontSize="30" FontFamily="Segoe UI Light" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid MaximumRowsOrColumns="2" Orientation="Horizontal" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,70,0" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
C#
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MedicinesApp
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public string getMedicinesName;
public ObservableCollection<Disease> diseaseList = new ObservableCollection<Disease>();
public MainPage()
{
this.InitializeComponent();
diseaseList.Add(new Disease { DiseaseName = "Malaria", DiseaseImageSource = "/Assets/133px-Malaria.jpg", CategoryOfDisease = "Blood" });
diseaseList.Add(new Disease { DiseaseName = "Typhod", DiseaseImageSource = "../Assets/apple.jpg", CategoryOfDisease = "Thorat" });
diseaseList.Add(new Disease { DiseaseName = "Cancer", DiseaseImageSource = "../Assets/orange.jpg", CategoryOfDisease = "Body" });
diseaseList.Add(new Disease { DiseaseName = "Headache", DiseaseImageSource = "../Assets/bilberry.jpg", CategoryOfDisease = "Brain" });
//diseaseList = new ObservableCollection<Disease>(diseaseList.OrderBy(c => c.DiseaseName));
MedicinesCollectionViewSource.Source = GetGroupsByLetter();
}
internal List<GroupInfoList<object>> GetGroupsByLetter()
{
var groups = new List<GroupInfoList<object>>();
var query = from item in diseaseList
orderby item.DiseaseName
group item by item.DiseaseName[0] into g
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{
var info = new GroupInfoList<object>();
info.Key = g.GroupName;
foreach (var item in g.Items)
{
info.Add(item);
}
groups.Add(info);
}
return groups;
}
public class GroupInfoList<T> : List<object>
{
public object Key { get; set; }
public new IEnumerator<object> GetEnumerator()
{
return base.GetEnumerator();
}
}
public class Disease
{
public string DiseaseName { get; set; }
public string DiseaseImageSource { get; set; }
public string CategoryOfDisease { get; set; }
}
private void MedicinesGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
getMedicinesName = ((Disease)MedicinesGridView.SelectedItem).DiseaseName;
}
private void MedicinesGridView_ItemClick(object sender, ItemClickEventArgs e)
{
this.Frame.Navigate(typeof(malaria), getMedicinesName);
}
}
the problem is whenever I click on Malaria,
it goes to the other page and shows cancer, which is the first vaule in the list.
How can I get the value of the item I click and not of the first item. I Have attached screenshot for you'll to get a better knowledge of things.
I looked at your code and there is one thing that I don't understand.
Why are you using 2 events to navigate. Only one would do the job.
private void MedicinesGridView_ItemClick(object sender, ItemClickEventArgs e)
{
var selectedDisease = e.ClickedItem as Disease;
this.Frame.Navigate(typeof(malaria), selectedDisease);
}
You don't need the getMedicinesName either.
Don't forget to remove the SelectionChanged event both from you code behind and XAML.
Related
So here I have a MVVM form. the Form contains a Datagrid which is connected to the Databank. I also have a ComboBox which I want to use as a filter option. The Filter option shoud filter by the "AnlV nr" so when the user selects "01" from the ComboBox the datagrid should refresh and show only that "AnlV nr" that have "01" Below I will share you the code and you can see that i've gotten as far as showing the "AnlV" values in the ComboBox but I now do not know how to do the rest and make the filter work. Below is my Viewmodel and the Xaml code.
If anyone can help me with this I would really apreciate it.
Xaml Code:
<Window x:Class="QBondsFrontend.Views.Input.AnlVTexteView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:QBondsFrontend.Views.Input" xmlns:input="clr-namespace:QBondsFrontend.ViewModels.Input" d:DataContext="{d:DesignInstance Type=input:AnlVTexteViewModel}"
mc:Ignorable="d"
Title="AnlVTexteView"
Width="800"
MinHeight="400"
Height="490"
MinWidth="1010"
MaxWidth="1010"
UseLayoutRounding="True">
<Grid Background="#A8A8A8" >
<StackPanel VerticalAlignment="Top" Background="#A8A8A8" Orientation="Horizontal" Height="57">
<Label
Content="AnlV Nr.:" Height="35" FontSize="12"/>
<ComboBox Background="LightGray" Height="20" Width="70" ItemsSource="{Binding lstAnlVTexte}" SelectedItem="{Binding Search}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding AnlVPara}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Height="18" Width="68" Margin="5, 0"
Content="Filter löschen" FontSize="11" Style="{StaticResource STL_ButtonStandard}"
x:Name="filterlöschen"
Command="{Binding icdFilterDelete}"/>
</StackPanel>
<StackPanel Background="LightGray" VerticalAlignment="Top" Height="177" Margin="0,57,0,0">
<DataGrid x:Name="datagridXAML"
Height="177"
ItemsSource="{Binding lstAnlVTexte, Mode=TwoWay}"
Style="{StaticResource STL_DataGridReporting}"
CellStyle="{StaticResource STL_DataGridCellReporting}"
ColumnHeaderStyle="{StaticResource STL_DataGridColumnHeaderReporting}"
AlternatingRowBackground="#A8A8A8"
CanUserResizeColumns="False"
>
<DataGrid.Columns>
<DataGridTextColumn Header="AnlV-Nr"
Binding="{Binding AnlVPara}"
Width="60"/>
<DataGridTextColumn Header="gültig ab"
Binding="{Binding TextGueltigAb}"
Width="68"/>
<DataGridTextColumn Header="Text"
Binding="{Binding ParaText}"
Width="750"/>
<DataGridTextColumn Header="Info"
Binding="{Binding Info}"
Width="*"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<StackPanel Background="#A8A8A8" HorizontalAlignment="Center" Margin="10,268,0,141" Width="1010" >
<Label Content="Bearbeitungsbereich" FontWeight="Bold" FontSize="12" Height="33" />
</StackPanel>
<StackPanel>
<StackPanel Orientation="Horizontal" Background="#A8A8A8" HorizontalAlignment="Center"
Width="1010" Margin="0,294,0,0" Height="31">
<Label Height="25" Width="60" Margin="20, 0, 0, 0" Content="AnlV-Nr.:" />
<ComboBox IsEditable="True" Background="gray" Height="22" Width="69" ItemsSource="{Binding AnlVPara}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding lstAnlVTexte}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<CheckBox Height="15" Margin="10, 0, 0, 0" />
<Label Height="26" Width="122" Content="Editierwarnungen" />
<StackPanel Height="48" Width="100"/>
</StackPanel>
<StackPanel Height="22" Orientation="Horizontal">
<Label Margin="20, 0, 0, 0" Content="gültig ab:" Height="27" />
<TextBox Background="LightGray" Height="20" Width="100" />
</StackPanel>
<StackPanel Height="50" Orientation="Horizontal">
<Label Content="Text:" Height="27" Width="38" Margin="42,0,0,10" />
<TextBox Background="LightGray" Width="500" Height="43" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<Label Content="Info:" Height="27" Width="38" Margin="42,0,0,0" />
<TextBox Background="LightGray" Width="500" Height="20" />
<Button x:Name="BTN_speichern" Width="80" Height="18" Margin="20,0,0,0" Content="Speichern"
Style="{StaticResource STL_ButtonStandard}" Command="{Binding icdSpeichern}"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
ViewModel:
using Newtonsoft.Json;
using QBondsData.DBModels;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Linq;
namespace QBondsFrontend.ViewModels.Input
{
public class AnlVTexteViewModel : BaseViewModel
{
#region data
private string _AnlVPara;
private DateTime _TextGueltigAb;
private string _ParaText;
private string _Info;
private List<AnlVhistText> _lstAnlVTexte;
private string _search;
#endregion
#region constructor
public AnlVTexteViewModel()
{
icdFilterDelete = new RelayCommand<object>(parameter => filterdelete(), parameter => true);
icdSpeichern = new RelayCommand<object>(parameter => speichern(), parameter => true);
GetData();
}
#endregion
#region members
public ICommand icdFilterDelete { get; set; }
public ICommand icdSpeichern { get; set; }
private string Search
{
get { return _search; }
set
{
_search = value;
OnPropertyChanged("Search");
}
}
public string AnlVPara
{
get
{
return _AnlVPara;
}
set
{
_AnlVPara = value;
OnPropertyChanged("AnlVPara");
}
}
public DateTime TextGueltigAb
{
get
{
return _TextGueltigAb;
}
set
{
_TextGueltigAb = value;
OnPropertyChanged("TextGueltigAb");
}
}
public string ParaText
{
get
{
return _ParaText;
}
set
{
_ParaText = value;
OnPropertyChanged("ParaText");
}
}
public string Info
{
get
{
return _Info;
}
set
{
_Info = value;
OnPropertyChanged("Info");
}
}
public List<AnlVhistText> lstAnlVTexte
{
get { return _lstAnlVTexte; }
set
{
_lstAnlVTexte = value;
OnPropertyChanged("lstAnlVTexte");
}
}
#endregion
#region methods
private void filterdelete()
{
}
private void speichern()
{
}
private async Task GetData()
{
HttpResponseMessage Response = await Globals.SendRequest("AnlVTexte/GetAnlVTexte"
, "GET");
if (Response.IsSuccessStatusCode)
{
lstAnlVTexte = JsonConvert.DeserializeObject<List<AnlVhistText>>
(await Response.Content.ReadAsStringAsync());
}
else
{
lstAnlVTexte = new List<AnlVhistText>();
Application.Current.Dispatcher.Invoke((Action)delegate
{
Globals.CloseReportByHash(this.GetHashCode()
, "Fehler! (HTTP Status " + Response.StatusCode + ")." +
"Kontaktieren Sie den Support.");
});
}
}
#endregion
}
}
When you change the type of lstAnlVTexte to ICollectionView you get two events CurrentChanged and CurrentChanging which you can handle in your viewmodel. From the ICollectionView you can get the CurrentItem.
Like this:
private List<AnlVhistText> _anlVTexte = new List<AnlVhistText>();
public AnlVTexteViewModel()
{
[...]
lstAnlVTexte = new CollectionView(_anlVTexte);
lstAnlVTexte.CurrentChanged += SelectionChanged; // raised after the current item has been changed.
lstAnlVTexte.CurrentChanging += SelectionChanging; // raise before changing the current item. Event handler can cancel this event.
}
private void SelectionChanged(object sender, EventArgs e)
{
var selectedItem = lstAnlVTexte.CurrentItem;
}
private void SelectionChanging(object sender, CurrentChangingEventArgs e)
{
}
private ICollectionView _lstAnlVTexte;
public ICollectionView lstAnlVTexte
{
get { return _lstAnlVTexte; }
set
{
_lstAnlVTexte = value;
OnPropertyChanged("lstAnlVTexte");
}
}
Here's a sample using the community toolkit mvvm and linq.
If you're not familiar, the toolkit does code generation.
This is a simple scenario to illustrate the approach.
Mainwindowviewmodel.
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private int selectedFilterInt = -1;
partial void OnSelectedFilterIntChanged(int newValue)
{
FilteredList = new ObservableCollection<MyItem>(FullList.Where(x=>x.Category == selectedFilterInt).ToList());
}
public List<int> FilterOptions { get; set; } = new List<int> {1,2,3};
private List<MyItem> FullList= new List<MyItem>
{
new MyItem{ Category = 1},
new MyItem{ Category = 1},
new MyItem { Category = 1 },
new MyItem { Category = 2 },
new MyItem { Category = 2 },
new MyItem { Category = 3 }
};
[ObservableProperty]
private ObservableCollection<MyItem> filteredList = new ObservableCollection<MyItem>();
public MainWindowViewModel()
{
FilteredList = new ObservableCollection<MyItem>(FullList);
}
}
There's a full list of all the items.
But a filtered list is going to be bound to the itemssource of my listbox ( equivalent to your datagrid ).
Due to the code generated, when selectedFilterInt changes, OnSelectedFilterIntChanged will be called. It's got a handler listening for property changed of SelectedFilterInt if you dug into the generated code.
That method uses a linq where to filter the full list into filtered list.
Setting that filtered list property raises property changed and the view re reads the new collection.
MainWindow. ( I did mention this is simplified )
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<StackPanel>
<ComboBox SelectedItem="{Binding SelectedFilterInt}"
ItemsSource="{Binding FilterOptions}"/>
<ListBox ItemsSource="{Binding FilteredList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Category}"/>
<TextBlock Text="{Binding Comment}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</Window>
and MyItem
public partial class MyItem : ObservableObject
{
[ObservableProperty]
private int category = 0;
[ObservableProperty]
private string comment = "Some test string";
}
Which is a bit underwhelming visually but works:
In your code you need to get all the data into a collection.
Call that FulList.
You then need another collection which will be the filtered data.
Call this FilteredList.
Bind itemssource to FilteredList
Initially, you presumably want FilteredList to be = FullList
Then when the user selects something in the combobox you need to react to that.
You could bind selecteditem to a property and act in the setter or handle propertychanged like my code does.
However you do it, you get a new integer.
You then use that to filter FullList into a new collection which will replace the bound FilteredList.
You also need to somehow have one entry per AnlV nr whatever that is in your combobox.
AnlV nr isn't going to work as a property name since it's got a space but it is the equivalent to Category in my sample.
You will use that selected value in the linq.
Substitute the name of that property for Category. Substitute the type of whatever your collection is. Maybe that's AnlVhistText. I'm not sure.
How can I make the dropdown sub-items clickable? i.e if I click on 'Employees' it will open the Employees page. I copied this from a tutorial however they didn't explain how to make click events with this creation.
Subitem Class
public class SubItem
{
public SubItem(string name, UserControl screen = null)
{
Name = name;
Screen = screen;
}
public string Name { get; private set; }
public UserControl Screen { get; private set; }
}
}
ItemMenu Class
public class ItemMenu
{
public ItemMenu(string header, List subItems, PackIconKind icon)
{
Header = header;
SubItems = subItems;
Icon = icon;
}
public ItemMenu(string header, UserControl screen, PackIconKind icon)
{
Header = header;
Screen = screen;
Icon = icon;
}
public string Header { get; private set; }
public PackIconKind Icon { get; private set; }
public List<SubItem> SubItems { get; private set; }
public UserControl Screen { get; private set; }
}
}
**UserControlMenuItem.xaml**
<Grid>
<materialDesign:PackIcon Kind="{Binding Path=Icon}" Width="15" Height="15" Margin="10 16" Foreground="White"/>
<ListBoxItem x:Name="ListViewItemMenu" Content="{Binding Path=Header}" Padding="37 14" FontSize="15" Foreground="White"/>
<Expander x:Name="ExpanderMenu" Header="{Binding Path=Header}" IsExpanded="False" Width="210" HorizontalAlignment="Right" Background="{x:Null}" Foreground="White">
<ListView x:Name="ListViewMenu" ItemsSource="{Binding Path=SubItems}" Foreground="White" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Padding="20 5"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</Grid>
**MainWindow.xaml**
<materialDesign:ColorZone Mode="PrimaryMid" Grid.ColumnSpan="2" HorizontalAlignment="Stretch">
<Grid>
<materialDesign:PopupBox PlacementMode="BottomAndAlignRightEdges" HorizontalAlignment="Right" Margin="10"/>
</Grid>
</materialDesign:ColorZone>
<Grid HorizontalAlignment="Stretch" Grid.Row="1" Background="{StaticResource PrimaryHueMidBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="326*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="GhostWhite">
<Image Source="Images/logo.png"/>
</Grid>
<ScrollViewer HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Grid.Row="1">
<StackPanel x:Name="Menu" Margin="10" />
</ScrollViewer>
</Grid>
<Frame Source="/CSA;component/Pages/Landing.xaml" Grid.Row="1" x:Name="ContentFrame" Grid.Column="1" Grid.ColumnSpan="2" Grid.RowSpan="2" Background="#2C2F33" Opacity="0.85" NavigationUIVisibility="Hidden" />
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var menuRegister = new List<SubItem>();
menuRegister.Add(new SubItem("Customer"));
menuRegister.Add(new SubItem("Providers"));
menuRegister.Add(new SubItem("Employees"));
menuRegister.Add(new SubItem("Products"));
var item6 = new ItemMenu("Register", menuRegister, PackIconKind.Register);
var menuSchedule = new List<SubItem>();
menuSchedule.Add(new SubItem("Services"));
menuSchedule.Add(new SubItem("Meetings"));
var item1 = new ItemMenu("Appointments", menuSchedule, PackIconKind.Schedule);
var menuReports = new List<SubItem>();
menuReports.Add(new SubItem("Customers"));
menuReports.Add(new SubItem("Providers"));
menuReports.Add(new SubItem("Products"));
menuReports.Add(new SubItem("Stock"));
menuReports.Add(new SubItem("Sales"));
var item2 = new ItemMenu("Reports", menuReports, PackIconKind.FileReport);
var menuExpenses = new List<SubItem>();
menuExpenses.Add(new SubItem("Fixed"));
menuExpenses.Add(new SubItem("Variable"));
var item3 = new ItemMenu("Expenses", menuExpenses, PackIconKind.ShoppingBasket);
var menuFinancial = new List<SubItem>();
menuFinancial.Add(new SubItem("Cash flow"));
var item4 = new ItemMenu("Financial", menuFinancial, PackIconKind.ScaleBalance);
var item0 = new ItemMenu("Dashboard", new UserControl(), PackIconKind.ViewDashboard);
Menu.Children.Add(new UserControlMenuItem(item0));
Menu.Children.Add(new UserControlMenuItem(item6));
Menu.Children.Add(new UserControlMenuItem(item1));
Menu.Children.Add(new UserControlMenuItem(item2));
Menu.Children.Add(new UserControlMenuItem(item3));
Menu.Children.Add(new UserControlMenuItem(item4));
}
```
All you need is to make the thing in ListView's ItemTemplate clickable. The easiest way to do that is to use a Button instead of a TextBlock. You can disable the Button's background and border to make it appear like text, but remain clickable.
Also, you don't need to use a ListView within an Expander. ListView offers scrolling capabilities and you don't need that. An ItemsControl will be enough.
Here's an example:
<Expander
Header="Expand me">
<ItemsControl ItemsSource="{Binding SubItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Background="Transparent"
BorderThickness="0"
Command="{Binding DataContext.DoSomethingCommand, ElementName=ThisWindow}"
Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
I'm binding to the same ICommand for all the sub items in this example. Realisticly, you would either pass a CommandParameter as well for the different sub items or bind to a different command per item.
After hours of searching the web I found a solution.
Method
public static void Navigate(object target)
{
((MainWindow)Application.Current.Windows[0]).ContentFrame.Content = target;
}
Implementation
switch (Globals.PageName)
{
case "Landing":
Pages.Landing itemZ = new Pages.Landing();
Navigate(itemZ);
break;
case "ClientAcquisition":
Pages.ClientAcquisition item = new Pages.ClientAcquisition();
Navigate(item);
break;
I want to Drag and Drop Item between Listbox. One is located in MainWindow and one in UserControl. Tab control items are dynamically coded.([VideoListing], [AddTab, AddItem]) I'm curious if this works and then give me directions.
This is what I wanted.
enter image description here
And, this is my Codes
Mainwindow.xaml
<TabControl x:Name="scenarioCB" ItemsSource="{Binding}" Grid.Row="1" HorizontalAlignment="Stretch" Margin="5,0,5,5" VerticalAlignment="Stretch" SelectionChanged="ScenarioCB_SelectionChanged">
<TabControl.ItemTemplate>
<DataTemplate DataType="local:AddTab">
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="local:AddTab">
<ListBox x:Name="listBox" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" ItemsSource="{Binding Data}" AllowDrop="True" Drop="ListBox_Drop" DragEnter="ListBox_DragEnter" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<MediaElement Margin="3" Source="{Binding Path}" Height="64" Stretch="Uniform" IsMuted="True"/>
<TextBlock Margin="3" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Mainwindow.xaml.cs
var tabs = new ObservableCollection<AddTab>();
for (int i = 0; i < DateListCount; i++)
{
var tab = new AddTab();
tab = new AddTab() { Header = DateList[i] + " - " + TimeList[i] };
tab.Data.Add(new AddData() { TIME = TimeList[i] });
Console.WriteLine("i = {0}, Header = {1}, Time = {2}", i, DateList[i], TimeList[i]);
tabs.Add(tab);
}
DataContext = tabs;
AddTab.cs
class AddTab
{
public string Header { get; set; }
public string Time { get; set; }
public ObservableCollection<AddData> Data { get; } = new ObservableCollection<AddData>();
}
AddData.cs
class AddData
{
public string NAME { get; set; }
public string PATH { get; set; }
}
VideoPanel.xaml
<ListBox Grid.Row="0" x:Name="listBox" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" AllowDrop="True" Drop="ListBox_Drop" DragEnter="ListBox_DragEnter" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<MediaElement Margin="3" Source="{Binding Path}" Height="64" Stretch="Uniform" IsMuted="True"/>
<TextBlock Margin="3" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
VideoPanel.xaml.cs
list.Add(new VideoListing()
{
Name = file_name,
Path = file,
});
VideoListing.cs
class VideoListing
{
public string Name { get; set; }
public string Path { get; set; }
}
If you have an example, please post the link.
Drag and Drop between listbox(MainWindow - UserControl)
Tabitems are dynamic coded
I solved this problem. Using by DragDrop.DoDragDrop
When I ran DragDrop.DoDragDrop(DependencyObject dragSourse, object data, DragDropEffects allowedEffects) when I pressed the left mouse button. And when I drop an item into another listbox, generate ListBox_Drop event. In LisetBox_Drop event, Just pull the data out of DragEventArgs.
Listbox - drag
private void ListBox_MouseMove(object sender, MouseEventArgs e)
{
DataObject dataObj = new DataObject();
dynamic Booth = listBox.SelectedItem as dynamic;
if (sender is ListBox && e.LeftButton == MouseButtonState.Pressed)
{
dataObj.SetData("Name", Booth.Name);
dataObj.SetData("Path", Booth.Path);
DragDrop.DoDragDrop(listBox, dataObj, DragDropEffects.Move);
}
}
Listbox - drop
private void ListBox_Drop(object sender, DragEventArgs e)
{
string name = (string)e.Data.GetData("Name");
string path = (string)e.Data.GetData("Path");
}
I have a list on page one with car objects. I want to click on a car from the list and click a button which will send the selected car to a list on another uwp page.
I am trying to put the listCar.selecteditems in an empty list I created called purchase and display purchase on page 2. With the code I have at the moment, it is only displaying ProjectName_Car in the list on page 2.
Any help on displaying this properly is appreciated.
Page1.xaml.cs
private void Add_Click(object sender, RoutedEventArgs e)
{
var query = listCars.SelectedItems.ToList().Cast<Car>();
foreach (var item in query)
{
purchase.Add(item);
}
liistCar.ItemsSource = purchase;
Frame.Navigate(typeof(Page2), listCar.Items);
}
Page2.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
lstCars.ItemsSource = e.Parameter as List<Car> ;
}
Edit: Page1.xaml
<ListBox Name="listCars" ItemsSource="{x:Bind cars}" >
<ListBox.ItemTemplate>
<DataTemplate x:DataType="Car">
<StackPanel Padding="20">
<Image Width="200" Height="150" HorizontalAlignment="Left" Source="{x:Bind imgCar}" />
<TextBlock FontSize="22" HorizontalAlignment="Left" Text="{x:Bind Name}" Style="{StaticResource HeaderTextBlockStyle}"/>
<TextBlock FontSize="16" HorizontalAlignment="Left"> € <Run Text="{Binding Price}" /></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This one transfers your selected car list object to next page as parameter with all its properties.
MainPage.xaml
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="YourPage"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel x:Name="Stacky" HorizontalAlignment="Stretch" Background="Aqua" VerticalAlignment="Stretch">
<ListBox Name="listCars" ItemsSource="{x:Bind cars}" SelectionMode="Multiple" Grid.Column="0" Grid.Row="1" Background="#FFF1EFEF" Opacity="0.7" Foreground="Black" Margin="10,10,94,10" Grid.RowSpan="2">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="local:Car">
<StackPanel Padding="20" BorderThickness="2" BorderBrush="Black">
<Image Width="200" Height="150" HorizontalAlignment="Left" Source="{x:Bind imgCar}" />
<TextBlock FontSize="22" HorizontalAlignment="Left" Text="{x:Bind name}" Style="{StaticResource HeaderTextBlockStyle}"/>
<TextBlock FontSize="16" HorizontalAlignment="Left"> € <Run Text="{x:Bind price}" /></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Done Selecting" Click="Add_Click"></Button>
</StackPanel>
</Page>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
List<Car> cars = new List<Car>();
public MainPage()
{
cars.Add(new Car() { imgCar = "ms-appx:///Assets/1.jpg", name = "Car1", price = "10000" });
cars.Add(new Car() { imgCar = "ms-appx:///Assets/2.jpg", name = "Car2", price = "10001" });
cars.Add(new Car() { imgCar = "ms-appx:///Assets/3.jpg", name = "Car3", price = "10002" });
this.InitializeComponent();
}
private void Add_Click(object sender, RoutedEventArgs e)
{
List<Car> mySelectedItems = new List<Car>();
foreach (Car item in listCars.SelectedItems)
{
mySelectedItems.Add(item);
}
Frame.Navigate(typeof(Page2), mySelectedItems);
}
}
public class Car
{
public string imgCar { get; set; }
public string name { get; set; }
public string price { get; set; }
}
Page2.xaml
<Page
x:Class="App1.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ListBox Name="listCars" SelectionMode="Multiple" Grid.Column="0" Grid.Row="1" Background="#FFF1EFEF" Opacity="0.7" Foreground="Black" Margin="10,10,94,10" Grid.RowSpan="2">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="local:Car">
<StackPanel Padding="20" BorderThickness="2" BorderBrush="Black">
<Image Width="200" Height="150" HorizontalAlignment="Left" Source="{x:Bind imgCar}" />
<TextBlock FontSize="22" HorizontalAlignment="Left" Text="{x:Bind name}" Style="{StaticResource HeaderTextBlockStyle}"/>
<TextBlock FontSize="16" HorizontalAlignment="Left"> € <Run Text="{x:Bind price}" /></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Page>
Page2.xaml.cs
public sealed partial class Page2 : Page
{
public Page2()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var items = e.Parameter as List<Car>;
listCars.ItemsSource = items;
base.OnNavigatedTo(e);
}
}
I am trying to build a diary app that uses hub as user interface and update the UI after saving the diary. I already implemented the INotifyPropertyChanged but it didn't work. I want the item that is added after saving to appear on the hub immediately.
public class SampleDataGroup : INotifyPropertyChanged
{
public SampleDataGroup()
{
UniqueId = string.Empty;
Title = string.Empty;
Subtitle = string.Empty;
Description = string.Empty;
ImagePath = string.Empty;
Items = new ObservableCollection<DiaryData>();
}
public string UniqueId { get; private set; }
public string Title { get; private set; }
public string Subtitle { get; private set; }
public string Description { get; private set; }
public string ImagePath { get; private set; }
private ObservableCollection<DiaryData> _items;
public ObservableCollection<DiaryData> Items { get{return _items;} private set
{
OnPropertyChanged("Items");
_items = value;
} }
public override string ToString()
{
if (this.Title != null)
{
return this.Title;
}
else
{
System.Diagnostics.Debug.WriteLine("this is null at tostring");
return null;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public sealed class SampleDataSource : INotifyPropertyChanged
{
private static SampleDataSource _sampleDataSource = new SampleDataSource();
private ObservableCollection<SampleDataGroup> _groups = new ObservableCollection<SampleDataGroup>();
public ObservableCollection<SampleDataGroup> Groups
{
get { return this._groups; }
set { }
}
public static async Task<IEnumerable<SampleDataGroup>> GetGroupsAsync()
{
await _sampleDataSource.GetSampleDataAsync();
return _sampleDataSource.Groups;
}
public static async Task<SampleDataGroup> GetGroupAsync(string uniqueId)
{
System.Diagnostics.Debug.WriteLine("GetGroupAsync is entered phase 1");
await _sampleDataSource.GetSampleDataAsync();
// Simple linear search is acceptable for small data sets
System.Diagnostics.Debug.WriteLine("GetGroupAsync is entered phase 2");
var matches = _sampleDataSource.Groups.Where((group) => group.UniqueId.Equals(uniqueId));
if (matches.Count() == 1) return matches.First();
return null;
}
public static async Task<DiaryData> GetItemAsync(string uniqueId)
{
await _sampleDataSource.GetSampleDataAsync();
System.Diagnostics.Debug.WriteLine("GetItemAsync is entered");
// Simple linear search is acceptable for small data sets
var matches = _sampleDataSource.Groups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
if (matches.Count() == 1) return matches.First();
else return null;
}
private async Task GetSampleDataAsync()
{
System.Diagnostics.Debug.WriteLine("GetSampleDataAsync is entered");
//if (this._groups.Count != 0)return;
Uri dataUri = new Uri("ms-appdata:///local/data.json");
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
string jsonText = await FileIO.ReadTextAsync(file);
JsonArray jsonArray = JsonArray.Parse(jsonText);
SampleDataGroup group = new SampleDataGroup();
foreach (JsonValue itemValue in jsonArray)
{
JsonObject itemObject = itemValue.GetObject();
group.Items.Add(new DiaryData(itemObject["Title"].GetString(),
itemObject["Content"].GetString(),
itemObject["Coordinate"].GetString(),
itemObject["UniqueId"].GetString(),
itemObject["ImagePath"].GetString(),
itemObject["VideoPath"].GetString()));
System.Diagnostics.Debug.WriteLine(itemObject["Title"].GetString());
}
this.Groups.Add(group);
System.Diagnostics.Debug.WriteLine("GetSampleDataAsync is finished");
}
//}
public event PropertyChangedEventHandler PropertyChanged;
}
here's my XAML File
<Page
x:Class="DiaryAppHub.HubPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DiaryAppHub"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:DiaryAppHub.Data"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
d:DataContext="{Binding Source={d:DesignData Source=/DataModel/SampleData.json, Type=data:data.json}}"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="HubSectionHeaderTemplate">
<TextBlock Margin="0,0,0,-9.5" Text="{Binding}"/>
</DataTemplate>
<!-- Grid-appropriate item template as seen in section 2 -->
<DataTemplate x:Key="Standard200x180TileItemTemplate">
<Grid Margin="0,0,9.5,9.5" Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="138.5" Width="138.5"/>
<TextBlock Text="{Binding Title}" VerticalAlignment="Bottom" Margin="9.5,0,0,6.5" Style="{ThemeResource BaseTextBlockStyle}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="StandardTripleLineItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0" Grid.Column="0" HorizontalAlignment="Left">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="79" Width="79"/>
</Border>
<StackPanel Grid.Column="1" Margin="14.5,0,0,0">
<TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Text="{Binding Description}" Style="{ThemeResource ListViewItemContentTextBlockStyle}" Foreground="{ThemeResource PhoneMidBrush}" />
<TextBlock Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="StandardDoubleLineItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0" Grid.Column="0" HorizontalAlignment="Left">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="79" Width="79"/>
</Border>
<StackPanel Grid.Column="1" Margin="14.5,0,0,0">
<TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}" Foreground="Black"/>
<TextBlock Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" Foreground="DimGray"/>
</StackPanel>
</Grid>
</DataTemplate>
</Page.Resources>
<Page.BottomAppBar>
<CommandBar Background="Transparent">
<AppBarButton Icon="Add" Label="Add" Click="add_onclick"/>
<AppBarButton Icon="Add" Label="Shake it!" />
</CommandBar>
</Page.BottomAppBar>
<Grid x:Name="LayoutRoot">
<Hub x:Name="Hub" x:Uid="Hub" Header="diary app hub" Margin="0,0,0,-59" Foreground="DimGray">
<Hub.Background>
<ImageBrush ImageSource="ms-appx:/Assets/desk_paper.png" Stretch="None"/>
</Hub.Background>
<!--<HubSection x:Uid="HubSection1" Header="SECTION 1" DataContext="{Binding Groups}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}">
<DataTemplate>
<ListView
ItemsSource="{Binding}"
IsItemClickEnabled="True"
ItemClick="GroupSection_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,27.5">
<TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</HubSection>-->
<HubSection x:Uid="HubSection5" Header="Recent"
DataContext="{Binding Groups[0]}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}">
<DataTemplate>
<ListView
AutomationProperties.AutomationId="ItemListViewSection5"
AutomationProperties.Name="Items In Group"
SelectionMode="None"
IsItemClickEnabled="True"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource StandardDoubleLineItemTemplate}"
ItemClick="ItemView_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
</ListView>
</DataTemplate>
</HubSection>
<HubSection x:Uid="HubSection2" Header="All notes" Width ="Auto"
DataContext="{Binding Groups[0]}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}" Height="659" >
<DataTemplate>
<GridView
Margin="0,9.5,0,0"
ItemsSource="{Binding Items}"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Items In Group"
ItemTemplate="{StaticResource Standard200x180TileItemTemplate}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
You need to raise the PropertyChanged event for the model's properties. The UI doesn't get notified as properties like Title,Subtitle don't raise the PropertyChanged event when they are modified. It should be like this:
private string _title;
public string Title
{
get
{
return _title;
}
set
{
if(_title!=value)
{
_title=value;
OnPropertyChanged("Title");
}
}
}
Do this similarly for other properties. Also, you don't need to raise the PropertyChanged event for an ObservableCollection as an ObservableCollection implements INotifyPropertyChanged by default.