Binding colors to ListPicker - c#

I'm trying to make a ListPicker control that contains a list of levels, with a colored square next to each level. This is what I've got:
<toolkit:ListPicker Grid.Row="1"
x:Name="LevelList"
Header="Level"
ItemCountThreshold="0"
FontFamily="Segoe WP Light">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding}"
Width="43"
Height="43" />
<TextBlock Text="{Binding}"
Margin="12 0 0 0" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Margin="16 21 0 20">
<Rectangle Fill="{Binding}"
Width="43"
Height="43" />
<TextBlock Text="{Binding}"
Margin="16 0 0 0"
FontSize="43"
FontFamily="{StaticResource PhoneFontFamilyLight}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
and in the c# part, I have
String[] Level= { "E1", "E2", "E3", "E4", "E5"};
String[] colors = { "#FFE5AD1B", "#FF0050EF", "#FFE51400", "#FF008A00", "#FFAA00FF" };
public TolonPk()
{
InitializeComponent();
this.listaNivel.ItemsSource = Level;
this.listaNivel.ItemsSource = colors;
}
My problem is that I don't know how to bind the Textblock strictly to the Level String array and the rectangle fill to the colors...
I'm probably missing something simple, but I just can't seem to get it...

if toolkit:ListPicker uses its ItemsSource like other WPF ItemsControl subclasses, then you need to have both the Level string and the Color string in the same list.
Make a little struct/class that contains a string for level and a string for color.
public struct LevelAndColor
{
public String Level { get; set; }
public String Color { get; set; }
}
Create some IEnumerable (List, ObservableCollection, etc.) and populate it with your instances of level-color pairs.
In the binding, bind like so:
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Color}" Width="43" Height="43"/>
<TextBlock Text="{Binding Level}" Margin="12 0 0 0"/>
</StackPanel>

Related

UWP NumberBox custom value template

I want to have a number-box like the image below, where the user can always see the maximum value [in my project the minimum value is always 1 and does not need to be shown], Is this possible? How should I do this?
<muxc:NumberBox Name="NumberBoxSpinButtonPlacementExample"
Header="Page"
Value="12" Minimum="1" Maximum="128"
SpinButtonPlacementMode="Compact"
SmallChange="1" LargeChange="10"
Width="100"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
I found the following code in this links [ WinUI NumberBox Control ], I think I should use this method, maybe not, I do not know
private DecimalFormatter DutchDecimalFormatter { get; } =
new DecimalFormatter(new[] { "nl-NL" }, "NL")
{
IsGrouped = true,
FractionDigits = 2,
NumberRounder = new IncrementNumberRounder {
Increment = 0.01,
RoundingAlgorithm = RoundingAlgorithm.RoundHalfUp,
}
};
Result :
<RelativePanel VerticalAlignment="Center" HorizontalAlignment="Center">
<muxc:NumberBox x:Name="nb1"
Header="صفحات"
Value="604" Minimum="1" Maximum="604"
SpinButtonPlacementMode="Compact"
SmallChange="1" LargeChange="10"
Width="100"/>
<Grid RelativePanel.AlignRightWith="nb1" Margin="0,24,30,0" Height="30" Background="#FF666666">
<TextBlock Name="nb1MaxValue" Text="604"
Foreground="White"
Padding="5,0"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</RelativePanel>
But why one number has an English format and the other a Persian format !!! O_O
NumberBox represents a control that can be used to display and edit numbers.
In your scenior, Number formatting can be used to format the value of a Numberbox, its result is still a number, not an expression such as 12/128.
I suggest that you could write a TextBlock to cover the NumberBox through RelativePanel like following.
<Page
……
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<RelativePanel BorderBrush="Red" BorderThickness="2" CornerRadius="10" Padding="12">
<muxc:NumberBox x:Name="MyNumberBox"
Header="Page" Value="15"
Minimum="1" Maximum="128"
SpinButtonPlacementMode="Compact"
SmallChange="1" LargeChange="10"
Width="150"
VerticalAlignment="Center"
HorizontalAlignment="Center" d:IsHidden="True"/>
<TextBlock x:Name="MyTextBlock" Text="/128" Margin="50,-30,0,0" RelativePanel.Below="MyNumberBox"/>
</RelativePanel>
</Grid>
</Page>
Result:

UWP access controls in ListViewItem from colletion

I have a ListView with two DataTemplate for items and headers.
Items from the ListView are binded to CollectionViewSource which looks like this:
<CollectionViewSource
x:Name="groupedItemsViewSource3"
Source="{Binding Groups2}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding Groups, Source={d:DesignData Source=/DataModel/SampleData.json, Type=data:SampleDataSource}}"/>
I can manage to get ListViewItem but I cant get control of its child controls.
My ListView looks like this:
<ListView
Margin="0,40,0,0"
Width="580"
HorizontalAlignment="Right"
x:Name="itemGridView1"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource2}}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Background="LightGray" Width="2500" Height="25">
<Border HorizontalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="Black">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Time}" Margin="10,0,0,0" Width="50" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{Binding LiveTime}" Foreground="{Binding LiveTimeBGColor}" Margin="10,0,0,0" Width="40" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{Binding TeamOne}" Margin="0,0,10,0" HorizontalTextAlignment="Right" Width="150" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<Border Background="DarkGray" Width="35" Margin="0,0,2,0" Padding="15,0,0,0">
<TextBlock Text="{Binding ScoreTeamOne}" Width="30" Foreground="White" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</Border>
<Border Background="DarkGray" Width="35" Padding="15,0,0,0" Margin="2,0,0,0">
<TextBlock Text="{Binding ScoreTeamTwo}" Foreground="White" Width="30" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</Border>
<TextBlock Text="{Binding TeamTwo}" Margin="10,0,0,0" HorizontalAlignment="Left" Width="150" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2" Width="2500" Background="{Binding HeaderLiveBGColor}">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextBlockButtonStyle}" Width="2500">
<StackPanel Orientation="Horizontal" Width="2500">
<TextBlock Text="{Binding LeagueTitle}" Margin="10,0,0,0" Width="441.9" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,20,0" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Any idea how can I check if the rights child control was clicked?
What I want to eventually achieve is the handle a click based on the controls of the ListViewItem clicked.
To get the clicked item from ListViewItem
If you add break points to debug your code, you could know there's a ClickedItem in ItemClickEventArgs class object. The ClickedItem should be that you want.
Another way is using TwoWay Binding on the SelectedItem.
Both the two ways are included in the following code sample:
<Page.Resources>
<CollectionViewSource
x:Name="groupedItemsViewSource3"
Source="{Binding Groups2}"
IsSourceGrouped="true"
ItemsPath="Items" />
</Page.Resources>
<Grid>
<ListView
Margin="0,40,0,0"
Width="580"
HorizontalAlignment="Right"
x:Name="itemGridView1"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource3}}"
SelectedItem="{Binding SelectedSong,Mode=TwoWay}"
SelectionMode="Single"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemGridView_ItemClick" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Background="LightGray" Width="2500" Height="25">
<Border HorizontalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="Black">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="10,0,0,0" Width="50" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2" Width="2500" Background="{Binding HeaderLiveBGColor}">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Style="{StaticResource TextBlockButtonStyle}" Width="2500">
<StackPanel Orientation="Horizontal" Width="2500">
<TextBlock Text="{Binding Key}" Margin="10,0,0,0" Width="441.9" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,20,0" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
public sealed partial class MainPage : Page
{
public ObservableCollection<SongGroup> Groups2 { get; set; }
private Song _SelectedSong;
public Song SelectedSong
{
get { return _SelectedSong; }
set
{
_SelectedSong = value;
}
}
public MainPage()
{
this.InitializeComponent();
Groups2 = GenerateData();
this.DataContext = this;
}
private ObservableCollection<SongGroup> GenerateData()
{
ObservableCollection<SongGroup> songGroups = new ObservableCollection<SongGroup>();
ObservableCollection<Song> songs = new ObservableCollection<Song>();
songs.Add(new Song() { Title = "Song1" });
songs.Add(new Song() { Title = "Song2" });
songGroups.Add(new SongGroup() { Key = "A", Items = songs });
ObservableCollection<Song> songs2 = new ObservableCollection<Song>();
songs2.Add(new Song() { Title = "Song2_1" });
songs2.Add(new Song() { Title = "Song2_2" });
songGroups.Add(new SongGroup() { Key = "B", Items = songs2 });
return songGroups;
}
private void ItemGridView_ItemClick(object sender, ItemClickEventArgs e)
{
var song = e.ClickedItem;
}
}
public class Song
{
public string Title { get; set; }
}
public class SongGroup
{
public string Key { get; set; }
public ObservableCollection<Song> Items { get; set; }
}

Data Will Not Bind WP

Im trying to bind data from a XML file, ive followed tuts from mdsn and other online sources but i keep getting an error, if i bind the data to a listbox it works fine.
public void LoadPage()
{
XDocument loadedData = XDocument.Load("page01.xml");
var data = from query in loadedData.Descendants("page")
select new PageReader
{
PageNumber = (int)query.Element("pnumber"),
ChapterTitle = (string)query.Element("ctitle"),
ChapterNumber = (int)query.Element("cnumber")
};
LayoutRoot.DataContext = data;
}
and the XAML
Grid x:Name="LayoutRoot" Background="#FFFFFEFE">
<StackPanel>
<Grid>
<Rectangle Fill="#FF424242" HorizontalAlignment="Left" Height="60" Stroke="Black" VerticalAlignment="Top" Width="480"/>
<StackPanel Orientation="Horizontal">
<TextBlock Width="100" TextWrapping="Wrap" MaxWidth="100" MaxHeight="58" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FFB6AEAE" FontFamily="{StaticResource lob2}" Text="{Binding ChapterNumber}"/>
<TextBlock Width="280" TextWrapping="Wrap" MaxWidth="300" MaxHeight="58" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FFB6AEAE" FontFamily="{StaticResource lob2}" Text="{Binding ChapterTitle}"/>
<TextBlock Width="100" TextWrapping="Wrap" MaxWidth="100" MaxHeight="58" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FFB6AEAE" FontFamily="{StaticResource lob2}" Text="{Binding PageNumber}"/>
</StackPanel>
</Grid>
<Grid Height="30"></Grid>
<TextBlock x:Name="PageText" Height="640" ScrollViewer.VerticalScrollBarVisibility="Visible"></TextBlock>
</StackPanel>
</Grid>
Your data is of type IEnumerable<PageReader>, which is why it would work with a ListBox as ListBox is expecting a collection.
If you change
LayoutRoot.DataContext = data;
to
LayoutRoot.DataContext = data.FirstOrDefault();
At least you should see some data show up on the UI.

Filling ListBox with custom control in windows phone

I am working on windows phone app where I need to get the latest streams from a site. I currently made a custom control that can hold each item from JSON:
<UserControl x:Class="TwitchStationApp.StreamItem"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="195" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Height="195" Width="469">
<Image Height="156" HorizontalAlignment="Left" Margin="12,12,0,0" Name="imageChannel" Stretch="Fill" VerticalAlignment="Top" Width="156" />
<TextBlock Height="84" HorizontalAlignment="Left" Margin="174,48,0,0" Name="textBlockStatus" Text="TextBlock" VerticalAlignment="Top" Width="294" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,12,0,0" Name="textBlockChanelName" Text="TextBlock" VerticalAlignment="Top" Width="294" Foreground="#FFB0CB3E" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,138,0,0" Name="textBlockViewers" Text="TextBlock" VerticalAlignment="Top" Width="294" />
</Grid>
</UserControl>
So I will make a list of items List<Stream> _stream = new ..... So this list will be populated by lets say 10 items. For each item I need to make a User control (above) and add it to the ListBox so that users can scroll and select (click/tap) on the item they want to get more information about.
What is the best way to do this? I checked microsoft website and there is something about having ItemTemplate in a XAML file in <Window.Resource> tag but I dont know where and how to create this file and link it to the listbox I have.
This is typically done using a data template.
Assuming you have a collection of StreamTypes
public class StreamType
{
public string Title { get; set; }
public string Description { get; set; }
}
You can define a Data template in
Application wide – in app.xaml
Page Scope – on the page
Control container scope – local to the container of the listbox
Within the Listbox itself
To define it page wide:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="SharedStreamTemplate">
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
In your list box, assign the data template to the item template
<ListBox x:Name="lstStreams" ItemTemplate="{StaticResource SharedStreamTemplate}" />
If there isn't a plausible cause for you to re-use the template, just assign it directly in the listbox
<ListBox x:Name="lstStreams">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Update
In your code behind
// Constructor
public MainPage()
{
InitializeComponent();
BindStreams();
}
private void BindStreams()
{
lstStreams.ItemsSource = new List<StreamType>
{
new StreamType { Description = "Description One", Title = "Title One"},
new StreamType { Description = "Description Two", Title = "Title Two"},
new StreamType { Description = "Description Three", Title = "Title Three"},
};
}
That's right you need to use the ItemsControl.ItemTemplate property. Using this property, you can specify a template that will be applied to each item in the list. Here's sample code:
Model:
public class Model
{
public string Name { get; set; }
public Guid Id { get; set; }
}
XAML
<ListBox ItemsSource="{Binding Path=MyItemsSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Id}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

WPF Bool DataTrigger - Change Font Colour

I want to change the font colour of a number of items on a WPF page based on the theme selected by the user. (there is a light theme, and a dark theme)
I'm using a datatemplate to customise the content of a listbox, when the theme is Dark, I want to change all the textblock font colours to White.
My the class behind the page I'm setting 'DarkTheme' to true.
I've successfully set triggers below, however I can't figure out how to do this from a value set on the pages class.
So, how can I style the font colour of the textblocks to white if DarkTheme = true?
Code:
public partial class Media : UserControl
{
public bool DarkTheme { get; set; }
readonly DatabaseAsset _dbAssets = new DatabaseAsset();
public Media()
{
InitializeComponent();
RefreshMediaList();
DarkTheme = Global.Configuration.IsDarkModeAppliedAsTheme();
}
}
XAML:
<UserControl.Resources>
<db:MediaAsset x:Key="MediaAsset"/>
<DataTemplate x:Key="MediaAssetItemTemplate">
<ListBoxItem Height="70" Name="ListBoxItem">
<DockPanel Margin="0,0,0,0" Height="65">
<DockPanel DockPanel.Dock="Left" Name="VideoImage2" Height="65" Width="102">
<Button Name="ListBoxItemSelect" Click="ButtonBase_OnClick" Tag="{Binding Path=Id}">
<Path Name="test" Width="38" Height="30.0833" Canvas.Left="19" Canvas.Top="22.1667" Stretch="Fill" Fill="#FF000000" Data="F1 M 19,34.8333L 22.1667,34.8333L 22.1667,42.75L 19,42.75L 19,34.8333 Z M 22.9583,34.0417L 49.4791,34.0417L 49.4791,38L 50.6667,38L 57,31.6667L 57,52.25L 50.6667,45.9167L 49.4791,45.9167L 49.4791,52.25L 22.9583,52.25L 22.9583,34.0417 Z M 29.2917,22.1667C 32.3522,22.1667 34.8333,24.6478 34.8333,27.7083C 34.8333,30.7689 32.3522,33.25 29.2917,33.25C 26.2311,33.25 23.75,30.7689 23.75,27.7083C 23.75,24.6478 26.2311,22.1667 29.2917,22.1667 Z M 41.9583,22.1667C 45.0189,22.1667 47.5,24.6478 47.5,27.7083C 47.5,30.7689 45.0189,33.25 41.9583,33.25C 38.8977,33.25 36.4167,30.7689 36.4167,27.7083C 36.4167,24.6478 38.8977,22.1667 41.9583,22.1667 Z "/>
</Button>
</DockPanel>
<DockPanel Dock="Left" Name="VideoData2" HorizontalAlignment="Stretch" Height="65">
<TextBlock DockPanel.Dock="Top" Text="{Binding Path=Title}" FontWeight="Bold" FontSize="18"></TextBlock>
<TextBlock DockPanel.Dock="Top" TextTrimming="CharacterEllipsis" Text="{Binding Path=Description}" TextWrapping="NoWrap" FontSize="13" Margin="0,0,0,0"/>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="{Binding Path=VideoCatNane}" FontSize="12" FontStyle="Italic"/>
<Border Width="50"></Border>
<TextBlock Text="{Binding Path=MediaState}" FontSize="12"/>
</StackPanel>
</DockPanel>
</DockPanel>
</ListBoxItem>
</DataTemplate>
</UserControl.Resources>
That's not the right way to do theming in WPF.
But if you want a quick solution, Move the InitializeComponent() statement to the bottom of your constructor:
public Media()
{
RefreshMediaList();
DarkTheme = Global.Configuration.IsDarkModeAppliedAsTheme();
InitializeComponent(); // <-- Here
}

Categories