I want to ListView with expander including some of information. So, I made this code. I'm not sure binding expander like that is correct. I just try to Binding like ListViewItem, But when I try to expander is not work at all. Here is my code.
XAML :
<Grid Grid.Row="2">
<ListView x:Name="lv">
<ListView.Template>
<ControlTemplate>
<HeaderedItemsControl>
<ItemsPresenter/>
</HeaderedItemsControl>
</ControlTemplate>
</ListView.Template>
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:LogBase}">
<Expander Grid.Column="0" HorizontalAlignment="Center">
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"> <!-- why this code is not wokring...? -->
<TextBlock Text="{Binding No}"/>
<TextBlock Text="{Binding Timestamp}"/>
<TextBlock Text="{Binding Type}"/>
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
code behind :
public partial class MainWindow : Window
{
public List<LogBase> logs { get; set; }
public MainWindow()
{
InitializeComponent();
logs = new List<LogBase>();
logs.Add(new LogBase()
{
No = "1",
Timestamp = "123456789",
Type = "Tcp"
});
logs.Add(new LogBase()
{
No = "2",
Timestamp = "123456789",
Type = "Tcp"
});
logs.Add(new LogBase()
{
No = "3",
Timestamp = "123456789",
Type = "Tcp"
});
lv.ItemsSource = logs;
DataContext = this;
}
}
public class LogBase
{
public string No { get; set; }
public string Timestamp { get; set; }
public string Type { get; set; }
}
for better understanding I captured what I want to
Now my program's situation
If you have any of opinions please comment for me!
You also need to bind the header to set the DataContext of the HeaderTemplate correct. This is done by Header="{Binding HeaderSource}". In your case just use Header="{Binding}" to bind directly to the item:
<Expander Header="{Binding}>
After that your code works perfectly.
Related
I want to bind an ObservableCollection to a ListView.
class TestClass
{
public string attribute1 { get; set; }
public string attribute2 { get; set; }
public string attribute { get; set; }
}
static public ObservableCollection<TestClass> GetTestClassCollection()
{
SpecialObjects[] specialobject = Class.GetSpecialObjects();
ObservableCollection<TestClass> specialTestObjects = new ObservableCollection<TestClass>();
foreach (SpecialObject special in specialobject)
{
specialTestObjects.Add(new TestClass() { attribute1 = special.attribute1, attribute2 = special.attribute2, attribute3 = special.attribute3 });
}
return specialTestObjects;
}
My MainWindow.xaml
<!-- Data Template -->
<Window.Resources>
<ListView x:Key="ListViewTemplate">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding attribute1}" />
<TextBlock Text="{Binding attribute2}" />
<TextBlock Text="{Binding attribute3}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Window.Resources>
... and here the method content to create the ListView (it's called when you click a button)
ListView listView = new ListView();
listView.ItemsSource = TestClass.GetTestClassCollection();
listView.ItemTemplate = (DataTemplate)this.FindResource("ListViewTemplate");
mainGrid.Children.Add(listView);
As soon as I click the button the application crash:
Unable to cast object of type 'System.Windows.Controls.ListView' to type 'System.Windows.DataTemplate'.
I searched for some ListView templates reference, but they all seem pretty similar to mine. But obviously, something doesn't match.
The application crash on the line when I try to assign ItemTemplate.
Thanks!
The error message is pretty clear.
(DataTemplate)this.FindResource("ListViewTemplate")
requires that the resource is a DataTemplate, but actually it is a ListView.
The resource declaration should look like this:
<Window.Resources>
<DataTemplate x:Key="ListViewTemplate">
<StackPanel>
<TextBlock Text="{Binding attribute1}" />
<TextBlock Text="{Binding attribute2}" />
<TextBlock Text="{Binding attribute3}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
What's the c# code to fill these listbox with datas (strings)
I saw this on https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview
but there's no C# Code.
I want to have a listbox like in "Defining a Simple DataTemplate" on the link
https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview
Picture from listbox [1]: https://i.stack.imgur.com/K4HZS.png
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
To do this, you will need to learn about MVVM pattern.
First, you need a class TODO in the model with properties for TaskName, Description and Priority.
public class Todo
{
public string TaskName { get; set; }
public string Description { get; set; }
public int Priority { get; set; }
}
Then, you will need a class to store the collection of TODO, your "myTodoList" in the xaml :
public class TodoViewModel
{
public ObservableCollection<Todo> TodoList { get; } = new ObservableCollection<Todo>();
public TodoViewModel()
{
TodoList.Add(new Todo { TaskName = "Todo1", Description = "Todo 1 Description", Priority = 1 });
TodoList.Add(new Todo { TaskName = "Todo2", Description = "Todo 2 Description", Priority = 2 });
}
}
Then, you will need to set the datacontext in the code behind of the xaml :
public partial class MainWindow : Window
{
public MainWindow()
{
this.DataContext = new TodoViewModel();
InitializeComponent();
}
}
Finally, here is your XAML (I changed it a bit, you don't need things like "Path=") :
<ListBox Width="400" Margin="10" ItemsSource="{Binding TodoList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding TaskName}" />
<TextBlock Text="{Binding Description}"/>
<TextBlock Text="{Binding Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And it should work well :)
You should have something like this.
MainWindow.xaml.cs:
public List<ToDo> ToDoList {get; set;}
public MainWindow()
{
InitializeComponent();
DataContext=this;
ToDoList= new List<ToDo>()
{
new ToDo{TaskName="Task1",Description="First Task"},
new ToDo{TaskName="Task2",Description="Second Task"}
};
}
ToDo.cs:
public class ToDo
{
public string TaskName {get; set;}
public string Description {get; set;}
}
Modify your Binding expression to:
<ListBox Width="400" Margin="10"
ItemsSource="{Binding ToDoList}">
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.
example
class abc
{
public ObservableCollection<string> Data { get; set; }
//data will be initialized in some functions
}
and wpf application
namespace WpfApplication
{
public partial class MainWindow : Window
{
[Import(typeof(GateManager))]
public abc _abc { get; set; }
public MainWindow()
{
InitializeComponent();
}
}
public void OnImportsSatisfied()
{
var binding = new Binding
{
Source = _abc,
Path = new PropertyPath("Data")
};
databox.SetBinding(ItemsControl.SourceProperty, binding);
//databox is name of the ItemControl like //<ItemsControl x:Name="databox" ScrollViewer.VerticalScrollBarVisibility="Auto">
// <ItemsControl.ItemTemplate>
// <DataTemplate>
// <StackPanel Orientation="Horizontal">
// <TextBlock Text="{Binding}" />
// </StackPanel>
// </DataTemplate>
//</ItemsControl.ItemTemplate>
//</ItemsControl> }
}
}
Im trying to do like this but this is not working
Add DataContext also
<Window.DataContext>
<ViewModel:ManageUserViewModel/>
</Window.DataContext>
in cs file :
private ObservableCollection<UserType> _listUserTypes = new ObservableCollection<UserType>();
public ObservableCollection<UserType> UserTypes
{
set
{
_listUserTypes = value;
}
get
{
return _listUserTypes;
}
}
In Xaml:
<ItemsControl ItemsSource="{Binding Path=UserTypes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public List<string> Data { get; set; }
in XAML,
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You want to set the ItemSource to the instance of an ObservableCollection you created in the constructor:
YourItemsControL.ItemsSource = Data ;
i stuck in a problem. i want to bind an image and text data in listpicker wp7. but when i bind image and text into listpicker only text bind. image not bind.
here is my code:
public void loadvehicaltype()
{
List<vehical> listofvehical = new List<vehical>();
listofvehical.Add(new vehical() { CarType= "Any Vehical" });
listofvehical.Add(new vehical() { CarType = "test1", carImage = "Images/car_Images/test_yellow.png" });
listofvehical.Add(new vehical() { CarType = "test2" });
listofvehical.Add(new vehical() { CarType = "Any Vehical" });
this.listPickerVehicalType.ItemsSource = listofvehical;
}
and here is vehical class :
public class vehical
{
public string CarType { get; set; }
public string carImage { get; set; }
}
and here is XAML :
<toolkit:ListPicker x:Name="listPickerVehicalType" Tap="listPickerVehicalType_Tap" SelectionMode="Single" ItemTemplate="{StaticResource ListPickerItemTemplate}" FullModeItemTemplate="{StaticResource ListPickerFullModeItemTemplate}" FullModeHeader="Items" CacheMode="BitmapCache"/>
and
<DataTemplate x:Name="ListPickerItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CarType}" Margin="10 0 0 0"/>
<!--<Image Source="{Binding carImage}" Margin="10,0,0,0" Stretch="None" />-->
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="ListPickerFullModeItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CarType}" Margin="10,0,0,0"/>
<Image Source="{Binding carImage}" />
</StackPanel>
</DataTemplate>
please help me to sort out this problem. i search this problem but no result found
This is because your image has it's build action set to Resource (Which is the default). you switch it to Content:
right click on your image and set it's build action to Content
Follow these link for more help
Follow these link for more help