unable to add textboxes to listbox - c#

hi I want to add textboxes to a listbox with everyclick on the add button.
so here are my codes
this.ListBox1.Controls.Add(TB);//TB is the name of my TextBox and it has been defined and initialized
I even tried to use Addat
there are no errors but it doesnt work

myYou don't want to add ListBox. Rather, add an object and define a default template for this object using a TextBlock.
So you define your local Namespace
xmlns:local="clr-namespace:MyNameSpace"
in the ressources you define your DataTemplate
<DataTemplate DataType="{x:type local:MyObjectType}">
<TextBlock Text="{Binding ThePropertyIWant}" />
</DataTemplate>
And in your code you just add object of type MyObjectType to your ListBox.
But even better, you add your objects to an ObservableCollection(Of MyObjectTYpe) and you bind that collection to your listBox. So when you add objects to the collection, the display is automatically updated.

Instead of using a ListBox you can use ListView, ListView has the ability to add custom column types
http://www.codeproject.com/Articles/9188/Embedding-Controls-in-a-ListView
http://weblogs.asp.net/scottgu/archive/2007/08/10/the-asp-listview-control-part-1-building-a-product-listing-page-with-clean-css-ui.aspx

Related

Display List of Custom Objects in a ListBox, Using a Custom User Control For Each

I have a list of objects (a custom class) that I want to display inside a ListBox, with each object drawing inside a custom User Control. Imagine a list of contacts (with custom Contact class) that should show up as a list of ContactUserControls (the XAML designed to present a Contact)
I know how to databind a list of Contact objects to a ListBox. I can databind a single Contact to a single ContactUserControl. I'm trying to understand the pattern/implementation of a databound list of objects that uses my custom UserControl to draw each object.
Do I bind the ListBox to my list of Contact objects, and (inside the Contact class) set up a connection to the ContactUserControl ("This is how you draw")? Do I bind the ListBox to a list of ContactUserControls, and bind each User Control to one of theses Contact objects before they go into the list? If so, do I have to do it manually via "ForEach" binding, or is there a "semi-magical" way in which it can be done purely via XAML?
Ideally, everything is correctly databound. Thanks! Not expecting somebody to present a turnkey solution of the entire thing, pointers to the applicable pattern/tutorials would be a great start.
You can use <ListBox.ItemTemplate>. Something like this:
<ListBox ItemsSource="{Binding contacts}">
<ListBox.ItemTemplate>
<DataTemplate>
<local:ContactUserControls DataContext="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
See https://msdn.microsoft.com/en-us/library/cc265158(v=vs.95).aspx the section about To format items in a ListBox or see https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate(v=vs.110).aspx the Examples section

Overwrite ListBoxitem?

I'm new to WPF and I have this ListBox which I want to instantiate with a specific ListBoxItem, so the user knows what to do with the ListBox.
<ListBox Name="DbListBox"
Grid.Column="3"
HorizontalAlignment="Left"
Height="246"
Margin="0,99,0,0"
Grid.Row="1"
VerticalAlignment="Top"
Width="211"
SelectionMode="Single"
SelectedItem="{Binding Path=selectedDB,Mode=TwoWay}"
AllowDrop="True"
Drop="DbListBox_Drop">
<ListBoxItem Name="ListBoxItem" FontStyle="Italic">Drag .db file here or add below</ListBoxItem>
</ListBox>
Then I have some code which adds a collection of items to the ItemsSource of this ListBox, but I can't do that since the ItemsSource is not empty
DbListBox.ItemsSource = DbCollection;
My question is, how can I start up the ListBox with the item inserted first, and then when DbCollection is added to it, it simply overwrites the first ListBoxItem?
When using WPF properly, we'd normally have something like this, where a collection property would be data bound to the ListBox.ItemsSource property:
<ListBox ItemsSource="{Binding SomeCollectionProperty}" />
Once we have this XAML, we don't need to touch the ListBox again, as we can add or remove items from the data bound collection and they will magically appear (or disappear) from the ListBox:
SomeCollectionProperty.Add(new SomeDataType());
SomeCollectionProperty.Remove(someItemFromCollection);
The SomeDataType used here is up to you... it depends on what you want to display in your items. If it was just a plain string for example, then you could simply do this to add your initial item into the collection:
SomeCollectionProperty.Add("Drag .db file here or add below");
If you wanted to make that item look different to the others then you'd need to data bind a custom class that has a Text property and FontStyle property for example. You could data bind these properties in a DataTemplate to design each item to be exactly as you want it. However, that's a completely different question.
To find out more about these things, you can read the Data Binding Overview and Data Templating Overview page on MSDN.

Data Template are only necessary in ItemsControl controls?

Let me explain you my situation.
I have a base class called Shape, and several concrete classes like Triangle, Square, etc.
I have several data templates.
I'm building just one object. So I wouldn't use an ItemControl control, I would like to use a normal panel like the grid, and show the respective data template (in DataContext has the concrete item)..
The only way to do this is using an ItemsControl? Or there's another way.. because I'm just using one item and not a collection and display the correct template.
DataTemplates are used in much more than just ItemsControls
They are used to tell WPF how to draw any object in the Visual Tree. For example, if you stick a User class object in the VisualTree, a DataTemplate can be used to tell WPF how to draw that User object
They are most frequently used in controls with an ItemsSource or Content properties, because those are the most common way of inserting data objects into the VisualTree.
In your specific case where you only want to insert one data item into the VisualTree, I would suggest a ContentControl
<ContentControl Content="{Binding MyDataObject}" />
To tell WPF how to draw MyDataObject you can either use the ContentTemplate property and set it to a DataTemplate
<ContentControl Content="{Binding MyDataObject}"
ContentTemplate="{StaticResource MyDataTemplate}" />
or define an implicit DataTemplate that tells WPF to draw any object of a specific type using a specific template.
<DataTemplate DataType="{x:Type local:MyDataObject}">
<!-- Tell WPF how to draw MyDataObject here -->
</DataTemplate>
If you want to display a single item with a data template that is selected based on the item's type, you should use ContentControl or any of its derived classes.

how to create binding in code when the datatemplate is declared in xaml

i have a datatemplate declared in xaml.
for e.g.
<DataTemplate x:Key="TestTemplate">
<StackPanel>
<TextBox Name="txtBox" Visibility="Visible"></TextBox>
</StackPanel>
</DataTemplate>
I wish to set the binding for txtBox in code behind before the element is generated because i have different binding paths for different elements that get generated
I can get the template in the code behind as :
DataTemplate tmplt = FindResource("TestTemplate") as DataTemplate;
but i am not sure what to do next. How to get the the txtBox reference to set the binding.
We have to remember one thing that Templates are not instantiated UI controls. They are streamed obejcts in XAML and are shared between UI elements. So if you edit a dataTemplate and change its stucture (by adding, editing, deleting an element under the template) it would change the one data template which is shared among controls. Thus other elements using that template will also be affected by the change.
Now lets address your issue of adding a dynamic biding to a textbox. You say each generated textbox will have different binding paths. So this definitely does NOT call for changing the data template itself!
You will have to access the text box and add dynamic bindings to it AFTER the textbox's is generated.
I see that your binding differs based on your "situation", so why cant you use TemplateSelector? Template selector will decide which data template (having one specific binding applied to the TetxBox) at runtime.
The first part of answer - is FindName() method.
example:
DataTemplate tmplt = FindResource("TestTemplate") as DataTemplate;
TextBox my = (TextBox)tmplt.FindName("txtBox");
try out this, it should help to get access to TextBox control. I think that you know how to bind to. If you want your DataBinding behave different way, use MultiBinding and Converter.
EDIT
public class GeneralObject
{
private object someObject;
public GeneralObject(object initObject)
{
this.someObject = initObject;
}
//If you want to bind to some text, for example
public string Text
{
get
{
//I think you know which objects are coming as input
if (this.someObject is SpecialClass1)
return ((SpecialClass1)this.someObject).SpecialClass1TextProperty;
if (this.someObject is SpecialClass2)
return ((SpecialClass2)this.someObject).SpecialClass2TextProperty;
//and so on.
}
}
}
EDIT 2
One more possible way
So I remember, that WPF have ContentControl!
<ContentControl Content="{Binding Path=CurrentObject}"/>
But in this case you have to create number of DataTemplate's, every Template for one class.
<DataTemplate DataType="{x:Type local:SpecialClass1}">
...
</DataTemplate>
<DataTemplate DataType="{x:Type local:SpecialClass2}">
...
</DataTemplate>
<!--and so on-->
WPF resolve DataTypes of ContentControl.Content property, and put to the ContentControl right DataTemplate.

Reapplying template for ListBox item programatically

Basically, I have a list of colors and a defined datatemplate for listbox item:
<DataTemplate x:Key="colorItemDataTemplate">
<Border x:Name="borderInner" BorderBrush="Black" BorderThickness="1" Background="{Binding Brush}" Width="11" Height="11" />
</DataTemplate>
Now, when I add a bunch of items into the listbox and then set the ListBox.ItemsSource property to my List, the listbox is filled correctly.
There is also a slider with its appropriate event handler. Within the event handler, Brush property of one of the items from the listbox is changed. Since the appearance of the item depends on the Brush Property, listbox should reflect the change.
I could reset the ItemsSource property, but then all items have their templates applied and with more than 200 items in the listbox, this is pretty slow.
So, is there any way to refresh the template for only one item from the listbox?
Thanx
I'm not sure I follow. If you've bound the Background to the property, changing the property should automatically udpate the background of the ListBoxItem. If you're not seeing that, make sure you are either using a DependencyProperty or implementing INotifyPropertyChanged.
You could use a binding converter. In the converter class you could have some logic like
(pseudo-code)
if (ListBoxItem.IsSelected)
return SpecialColorFromSlider
else
return NormalListBoxColor

Categories

Resources