Passing a global value to DateTemplate in WPF - c#

I have the following ListView with a DataTemplate that creates three TextBlocks and populates each entry with the data from class Item.
I want to set the width of each TextBlock to some value that is passed through with the ICollection<Item> array as a value that is the same for each entry. With the syntax below, each Item would have to have the values of GlobalWidth1, etc to be set for each instance.
Is there any way to pass the width values as a global values for the entire ICollection<Item> collection in WPF?
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Data1}" Width="{Binding GlobalWidth1}" />
<TextBlock Text="{Binding Data2}" Width="{Binding GlobalWidth2}" />
<TextBlock Text="{Binding Data3}" Width="{Binding GlobalWidth3}" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class Item
{
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
}

Instead of using bindings you could define resource values within the XAML file itself and use {StaticResource ...}.
xmlns:system="clr-namespace:System;assembly=System.Runtime"
...
<ListView>
<ListView.Resources>
<system:Double
x:Key="GlobalWidth1">
100
</system:Double>
<system:Double
x:Key="GlobalWidth2">
120
</system:Double>
<system:Double
x:Key="GlobalWidth3">
150
</system:Double>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Data1}" Width="{StaticResource GlobalWidth1}" />
<TextBlock Text="{Binding Data2}" Width="{StaticResource GlobalWidth2}" />
<TextBlock Text="{Binding Data3}" Width="{StaticResource GlobalWidth3}" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You could even have these defined in your top level App.Resources and set them from the App.xaml.cs.
Note: If you add these to the App.Resources you will need to remove them from the local ListView.Resources
public App()
{
//hardcode
this.Resources.Add("GlobalWidth1", 100);
this.Resources.Add("GlobalWidth2", 120);
this.Resources.Add("GlobalWidth3", 150);
//or perhaps define them in the global settings
this.Resources.Add("GlobalWidth1", Settings.Default.GlobalWidth1);
this.Resources.Add("GlobalWidth2", Settings.Default.GlobalWidth2);
this.Resources.Add("GlobalWidth3", Settings.Default.GlobalWidth3);
}
Of course if you want to keep it using bindings you can just add static properties on the Item class:
public class Item
{
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
public static double GlobalWidth1 => 100;
public static double GlobalWidth2 => 120;
public static double GlobalWidth3 => 150;
}
I would personally recommend keeping it in the XAML for I find it more organized to keep pure UI code in the View layer and out of the ViewModel layer (If you are sticking to MVVM)

Related

WPF ItemsSource binding show only last item of list

How to show only last item of the list in itemssource binding ?
below is my current code.
xaml
<ItemsControl ItemsSource="{Binding UpgradeTicketStorage}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Width="800">
<TextBlock Text="{Binding TicketTitle}" Style="{StaticResource TicketSelectionSubTitle}" TextAlignment="Left" />
<TextBlock Text="{Binding TicketDescription}" TextWrapping="Wrap" Style="{StaticResource TicketSelectionSubTitle2}" FontSize="19" TextAlignment="Left"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
from class binding i do have added 2 records which is ticketA and ticketB, how can i just display ticketB information ? instead of A and B
class
public class UpgradeTicketDescription : ViewModelBase
{
public string TicketTitle { get; set; }
public string TicketDescription { get; set; }
}
List<UpgradeTicketDescription> _UpgradeTicketStorage;
public List<UpgradeTicketDescription> UpgradeTicketStorage
{
get { return _UpgradeTicketStorage; }
set { _UpgradeTicketStorage = value; OnPropertyChanged("UpgradeTicketStorage"); }
}
UpgradeTicketStorage.Add(new UpgradeTicketDescription { TicketTitle = "TicketA", TicketDescription = "Observation DeckA (Single Ticket)"});
UpgradeTicketStorage.Add(new UpgradeTicketDescription { TicketTitle = "TicketB", TicketDescription = "Observation DeckB (Single Ticket)"});
If you want to bind to a specific item in a list you can go about it by creating a public variable you will bind to. Using what you have provided I've created an example that works for the last item in the list, all I did is create a new variable called LastItem and changed how the binding is in the project. This is just one of many ways of going about this.
xaml
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Width="800">
<TextBlock Text="{Binding LastItem.TicketTitle}" TextAlignment="Left" />
<TextBlock Text="{Binding LastItem.TicketDescription}" TextWrapping="Wrap" FontSize="19" TextAlignment="Left"/>
</StackPanel>
class
public UpgradeTicketDescription LastItem
{
get { return UpgradeTicketStorage.Last(); }
}
This provides this output:

Invalid binding path 'MyStatic' : Property 'MyStatic' can't be found on type 'CreatePage' [duplicate]

This question already has answers here:
Update Listview with Object Data
(1 answer)
Static binding doesn't update when resource changes
(2 answers)
Closed 6 years ago.
So I've been looking for the wright solution for my problem. It seems I'm not able to bind to a observableCollection that is located in my models folder. I am able to add items in it and in a later stadium retrieve these with some C# Code. BUT I just can't seem to bind to the items from a page I named CreatePage.
I keep getting this message: Invalid binding path 'Questionlist' : Property 'Questionlist' can't be found on type 'CreatePage'.
Class with the observableCollection:
public partial class MyStatic
{
static MyStatic()
{
Questionlist = new ObservableCollection<QuestionList>();
}
public static ObservableCollection<QuestionList> Questionlist;
}
public class QuestionList
{
public string Question { get; set; }
public string Answer { get; set; }
public string Delete { get; set; }
public string Correct { get; set; }
public string Wrong { get; set; }
public string UserAnswer { get; set; }
}
This is my Xaml:
<ScrollViewer Grid.Row="4"
Grid.ColumnSpan="2"
Margin="20,10"
MaxWidth="650">
<RelativePanel>
<ListView Name="Questionviewlist"
ItemsSource="{x:Bind Questionlist}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:QuestionList">
<TextBlock Name="Questionview"
Text="{x:Bind Question}"
TextWrapping="Wrap"
FontFamily="Arial Rounded MT Bold"
FontWeight="Bold"
Foreground="Brown"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Name="Answerviewlist"
RelativePanel.AlignHorizontalCenterWithPanel="True"
ItemsSource="{x:Bind Questionlist}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:QuestionList">
<TextBlock Name="Answerview"
Text="{x:Bind Answer}"
FontFamily="Arial Rounded MT Bold"
FontWeight="Bold"
Foreground="Brown"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Name="Deleteviewlist"
RelativePanel.AlignRightWithPanel="True"
ItemsSource="{x:Bind Questionlist}"
IsItemClickEnabled="True"
ItemClick="Deleteviewlist_ItemClick">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:QuestionList">
<TextBlock Name="Deleteview"
Text="{x:Bind Delete}"
TextWrapping="WrapWholeWords"
Foreground="#FFB57C"
FontStyle="Italic"
FontFamily="Arial Rounded MT Bold"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
</ScrollViewer>

How generate(binding) quiz in form using wpf mvvm

How binding quiz with different type questions in WPF app using MVVM?
QuizPageViewModel:
public class QuizPageViewModel : ViewModelBase
{
public QuizPageViewModel()
{
QuizCollection = new ObservableCollection<QuizQuestion>();
}
public ObservableCollection<QuizQuestion> QuizCollection { get; set; }}
Where QuizQuestion: - EF Entity
public partial class QuizQuestion
{
public QuizQuestion()
{
QuizAnswers = new HashSet<QuizAnswer>();
QuizMultiQuestions = new HashSet<QuizMultiQuestion>();
}
public long Id { get; set; }
public int QuizId { get; set; }
***public String Type { get; set; }***
[Required]
public string Name { get; set; }
}
Question Type can be truefalse, multianswer, multichoice and other type
in xaml:
<ItemsControl ItemsSource="{Binding QuizCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding Path=QuizAnswers}"
VerticalAlignment="Stretch"
Background="Transparent">
<ListBox.ItemTemplate>
<ItemContainerTemplate>
<RadioButton GroupName="{Binding Id}"
Content="{Binding Name}" />
</ItemContainerTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
this xaml code display only radiobutton question of quiz. How binding and display other Type of question (checkbox, combobox, textbox)? HELP)))
You can use an Item template selector in your items control to display different controls/templates depending on the question.
In the code below you can see that there's a conditional statement that checks the type of question and return a template based on the type of question.
public class QuiztemplateSelector : DataTemplateSelector
{
public DataTemplate TrueOrFalseTemplate { get; set; }
public DataTemplate MultiAnswerTemplate { get; set; }
public DataTemplate MultiChoiceTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var question = item as QuizQuestion;
if (question.Type.Equals("TruOrFalse"))
return TrueOrFalseTemplate;
else if (question.Type.Equals("MultiAnswer"))
return MultiAnswerTemplate;
else if ("MultiChoice")
return MultiChoiceTemplate;
return null; //Or your default Template.
}
}
Now in your xaml, you can create templates for the types of questions (i.e. true/False, Multi choice, multi answer). Then you need to pass those templates to the QuiztemplateSelector as shown below.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<DataTemplate x:Key="TrueOrFalse">
<!-- Write your True or false template here-->
</DataTemplate>
<DataTemplate x:Key="MultiChoice">
<!-- Write your MultiChoice template here-->
</DataTemplate>
<DataTemplate x:Key="MultiAnswer">
<!-- Write your multianswer Template here -->
</DataTemplate>
<local:QuizTemplateSelector x:Key="QuizTemplateSelector"
MultiAnswerTemplate="{StaticResource MultiAnswer}"
TrueOrFalseTemplate="{StaticResource TrueOrFalse}"
MultiChoiceTemplate="{StaticResource MultiChoice}" />
</Grid.Resources>
<ItemsControl ItemsSource="{Binding QuizCollection}" ItemTemplateSelector="{StaticResource QuiztemplateSelector}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding Path=QuizAnswers}"
VerticalAlignment="Stretch"
Background="Transparent">
<ListBox.ItemTemplate>
<ItemContainerTemplate>
<RadioButton GroupName="{Binding Id}"
Content="{Binding Name}" />
</ItemContainerTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
You can read more abour DataTemplateSelector here.

c# WPF CellTemplate / DataTemplate for an Image list / array

What I have:
my class:
public class MyImage
{
public String ImagePath { get; private set; }
public String Name { get; private set; }
// ...
}
XAML:
<Window.Resources>
<DataTemplate x:Key="template_image">
<Image Source="{Binding Path=ImagePath}" Stretch="None" />
</DataTemplate>
<DataTemplate x:Key="template_name">
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</Window.Resources>
<ListView x:Name="gui_listview_graphics" Margin="75,0,0,0">
<ListView.View>
<GridView>
<GridViewColumn Header="Graphic" CellTemplate="{StaticResource template_image}" />
<GridViewColumn Header="Name" CellTemplate="{StaticResource template_name}" />
</GridView>
</ListView.View>
</ListView>
Works fine.
Now what i now want..
I need to display an Image-List instead of just one Image.
my new class:
public class MyNewImage
{
public ObservableCollection<String> ImagePath { get; private set; }
public String Name { get; private set; }
// ...
}
The DataTemplate should contain an Stackpanel which contains all images..
Is it possible?
If yes, how ..
Thank you!
In your DataTemplate include an ItemsControl whose Items property is bound to your collection of image paths. Your ItemTemplate for the ItemsControl will essentially be the same as your current DateTemplate, except you will use an implicit Binding for the Image source, since the string itself is your object. The default template for the ItemsPanel for an ItemsControl is a StackPanel already, but you can change this if necessary by setting the ItemsPanel property.
This template should work:
<DataTemplate x:Key="template_image_list">
<ItemsControl ItemsSource="{Binding ImagePath}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"></Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
Because a StackPanel does not have a property ItemsSource, you cannot bind directly to it. If you use it as ItemsPanelTemplate of an ItemsControl everything is fine.

DataBinding to WP8 Toolkit ExpanderView

I'm attempting to databind to a Windows Phone 8 Toolkit Expander view with the following XAML and C# class. I know that the DataContext is set properly because the Headers have the proper text. However, the rest of the items aren't set properly (except for the ExpanderTemplate)
<phone:PanoramaItem Header="Skill Sheet">
<ListBox Name="SkillSheet" ItemsSource="{Binding}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:ExpanderView Header="{Binding}"
ItemsSource="{Binding}"
IsNonExpandable="False">
<toolkit:ExpanderView.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding groupName}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" LineHeight="{StaticResource LongListSelectorGroupHeaderFontSize}" />
</DataTemplate>
</toolkit:ExpanderView.HeaderTemplate>
<toolkit:ExpanderView.ExpanderTemplate>
<DataTemplate>
<TextBlock Text="Test" />
</DataTemplate>
</toolkit:ExpanderView.ExpanderTemplate>
<!--This is the area that is not getting databound-->
<toolkit:ExpanderView.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding skillNames}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding skill}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</toolkit:ExpanderView.ItemTemplate>
</toolkit:ExpanderView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PanoramaItem>
And here are the classes that the XAML is getting bound to:
public class TreeMapSkill
{
public string skill { get; set; }
}
public class TreeMapping
{
public string groupName { get; set; }
public List<TreeMapSkill> skillNames { get; set; }
public TreeMapping()
{
skillNames = new List<TreeMapSkill>();
}
}
public class TreeMappingList
{
public List<TreeMapping> mapping { get; set; }
public TreeMappingList() { }
public TreeMappingList(Dictionary<string, List<string>> map)
: base()
{
this.mapping = new List<TreeMapping>();
foreach (string key in map.Keys)
{
TreeMapping tMap = new TreeMapping();
tMap.groupName = key;
foreach (string val in map[key])
tMap.skillNames.Add(new TreeMapSkill() { skill = val });
this.mapping.Add(tMap);
}
}
The Dictionary in the constructor is simply a list of skills associated to a specific group. I can also provide a sample object if it's needed for additional reference.
Why are you adding a ListBox inside the Expander's ItemTemplate? It is already a controls collection so you don't need a ListBox in there. Just put your DataTemplate inside.
<toolkit:ExpanderView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding skill}" />
</DataTemplate>
</toolkit:ExpanderView.ItemTemplate>
The second thing is you need to specify the property path on the binding of the ItemSource property for the expander.
<toolkit:ExpanderView Header="{Binding}"
ItemsSource="{Binding skillNames}"
IsNonExpandable="False">

Categories

Resources