Let me explain so I have a wpf application I used a listBox with a template. This template contains a TextBlock and a ComboBox. When running the application, everything goes well, my list is initialized correctly. But then I would like to retrieve the values of my TextBlock and my comboBox and I don't understand how I can achieve this.
I am attaching the part of my XAML code that deals with this listBox :
<ListBox x:Name="ListBoxEnv" Grid.Row="1"
d:ItemsSource="{d:SampleData ItemCount=5}" Width="460"
SelectionChanged="ListBoxEnv_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="TxtBlockEnv"
VerticalAlignment="Center" HorizontalAlignment="Left"
Text="{Binding EnvName}"/>
<ComboBox x:Name="ComboBoxEnv"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding EnvListValue}"
Margin="100,2,0,2" Width="200"
SelectionChanged="ComboBoxEnv_SelectionChanged"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The EnvName property is readonly because it is bound to TextBlock, so you can ignore it. Change binding to: Text="{Binding EnvName, Mode=OneTime}" to save the app resources.
However to extract selected environment in every combo in the list you need to add to ComboBox template: SelectedItem={Binding SelectedEnv} and add new property to SampleData
for example
public MyEnvironmentClass SelectedEnv {get; set;}
Related
I have a list view that will contain notes that I input. I am having trouble figuring out how to have the list view item look how I want it to.
Below is how it should look:
And this is what it currently looks like:
How do I write the list view item in XAML so that the Date and time appear to the very top-right of each list view item, with the text of the note to the left?
<ListView x:Name="list" ItemsSource="{Binding Note}" BorderBrush="{x:Null}" BorderThickness="0">
<DataTemplate>
<ListViewItem>
<StackPanel Orientation="Horizontal">
</StackPanel>
</ListViewItem>
</DataTemplate>
</ListView>
Any help at all is much appreciated!
You are missing a number of elements required in order to get your screen to look the way you want.
You need to define the ItemTemplate for the ListView. You're on the right track here, it is a DataTemplate declared in XAML, you just have to apply it to the ListView.ItemTemplate property.
You need to set the HorizontalContentAlignment of the ListView to Stretch (the default is Left, which means your items will not fill the entire content area).
You need to use a DockPanel (or other similar panel) inside your DataTemplate to place your date content on the right, and the remainder of your content on the left.
You need to disable Horizontal Scrolling (ScrollViewer.HorizontalScrollBarVisbility) on the ListView in order to make your content wrap (otherwise it will just happily draw it all on one line).
I've included a sample ListView that should get you started.
<ListView
ItemsSource="{Binding Items}"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock
TextWrapping="Wrap"
Text="{Binding Date}"
Background="Magenta"
DockPanel.Dock="Right" />
<TextBlock Text="{Binding Content}" Background="Lime" />
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Okay, So I am trying to bind a list of objects with a DisplayName property to a long list selector.
XAML Code
<phone:LongListSelector x:Name="lls_TemplateFields" HorizontalAlignment="Left" Width="450" Grid.Row="2" Height="400" LayoutMode="List" Background="#FF9E9D9D" IsGroupingEnabled="False">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding DisplayName}" Foreground="Black" FontSize="24"/>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
C# Code
List<AttributeDefinition> m_SelectedAttributes = new List<AttributeDefinition>();
lls_TemplateFields.ItemsSource = m_SelectedAttributes;
My Class AttributeDefinition contains a property for DisplayName. If I group the the list using a group key then the list will show up, however I cannot get just a plain list of items to show up. Like a listbox in WPF C#.
I am using this list to represent a list of chosen AttributeDefinitions from another list that shows all the AttributeDefinitions grouped alphabetically by their DisplayName property, and the Display Value is Binded to the DisplayName Property like shown below...
XAML
<phone:LongListSelector x:Name="lls_AttributeList" HorizontalAlignment="Left" Height="450" VerticalAlignment="Top" Width="450" HideEmptyGroups="True" IsGroupingEnabled="True" SelectionChanged="SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="2">
<TextBlock Text="{Binding DisplayName}" Foreground="{StaticResource PhoneChromeBrush}" FontSize="24"/>
</Border>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
<phone:LongListSelector.GroupHeaderTemplate>
<DataTemplate>
<Grid Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Center" Background="Blue">
<Border BorderThickness="4">
<TextBlock Text="{Binding Key}" Foreground="White" FontSize="38" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
</DataTemplate>
</phone:LongListSelector.GroupHeaderTemplate>
</phone:LongListSelector>
C#
List<AttributeKeyGroup<AttributeDefinition>> DataSource = AttributeKeyGroup<AttributeDefinition>.CreateGroups(AttributeData,
Thread.CurrentThread.CurrentUICulture,
(AttributeDefinition aDef) => { return aDef.Type; },
true);
lls_AttributeList.ItemsSource = DataSource;
This list works just fine. And the data in the background is functioning properly, because as I select items from the total list of attributedefinitions they are removed from the LongListSelector and added to the LongListSelector of the selected lists Itemssource
For further inquiry into more code surrounding this User Control please feel free to ask I will disclose as much code as I can without breaking my non-disclosure agreement with my work. Thank you for taking the time to read and possibly help. Much appreciated.
List<AttributeDefinition> m_SelectedAttributes = new List<AttributeDefinition>();
lls_TemplateFields.ItemsSource = m_SelectedAttributes;
because you just instantiated this list and binding it right away? How about adding some items into the list
There are two answers to this. I have tried both and both work.
[1] You have to set the LongListSelector.ScrollTo(object) to the first object of your list when you update the data if the list has 1 or more items. Such as...
lls_TemplateFields.ItemsSource = m_SelectedAttributes;
if(m_SelectedAttributes.Count > 0)
{
lls_TemplateFields.ScrollTo(m_SelectedAttributes[0]);
}
[2] The proper way to fix this is to use ObservableCollections which work better with DataBinding and the WP8 WPF SDK UI to update on adding objects to the ObservableCollection.
ObservableCollection<AttributeDefinition> m_SelectedAttributes =
new ObservableCollection<AttributeDefinition>();
lls_TemplateFields.ItemsSource = m_SelectedAttributes
I'm stuck again at some data-binding issue.
This time I want to bind a ListView to the SelectedItem of a GridView. I already suceed with this type of data-binding but now my ListView, which should show some details about my selected item in my GridView just stays empty. There are no items in it although they should exist.
The GridView binds just fine at the property in my MainViewModel.Substituting the ElementName attribute with x:Resouces doesn't seem to be an option, because it doesn't work either.
The source view:
<GridView x:Name="gridViewOrderYears"
ItemsSource="{Binding SelectedCustOrders, Mode=TwoWay}"
HorizontalAlignment="Left"
Grid.Row="1"
VerticalAlignment="Top"
Width="316"
Height="63"
Margin="657,316,0,0"
SelectionMode="Single">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="1" BorderBrush="Aquamarine">
<StackPanel>
<TextBlock Text="{Binding Year}" FontSize="20"/>
<TextBlock Text="{Binding OrderCount}"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
this View doesnt bind:
<ListView HorizontalAlignment="Left"
Height="231"
Margin="657,401,0,0"
Grid.Row="1"
VerticalAlignment="Top"
Width="316"
DataContext="{Binding SelectedItem, ElementName=gridViewOrderYears}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DoneOrders.Order_Date, ElementName=gridViewOrderYears}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
SelectedCustOrders porperty is an IList<OrderYears>.
OrderYears is following data value object defined in my MainViewModel:
public class OrderYears
{
public int? Year { get; set; }
public IList<Orders> DoneOrders { get; set; }
public int OrderCount { get; set; }
}
I think the problem is in the ListView binding, because you try to bind to a property named "Orders", which does not exist in the OrderYears object. You have a property named DoneOrders which you can bind to (don't confuse the property name with the type of elements inside the list!), but if you bind a TextBlock to a IList you will just get the guid for the IList object.
Try something like this, replacing you ListView with a ListBox (which is enough for what you are trying to do here):
<ListBox DataContext="{Binding ElementName=gridViewOrderYears,
Path=SelectedItem.DoneOrders}"
DisplayMemberPath="Order_Date"/>
There is no need to create a template, the items inside the ListBox will be displayed like a TextBlock. Note that you can benefit from binding to nested properties like MainProperty.SubProperty.
Let me know if this was helpful, bindings can be such a headache when you are starting...
Finally I got it.
After hours of trial-and-error finally substituting DataContext with ItemsSource did the trick... Sometimes things are easier than you think :)
i'm trying to change the font size for my items in a listpicker.
I use a fullmodeitemtemplate to be able to change fontsize etc.
The problem is that i have no idea how to bind the text for the items in the template
<DataTemplate x:Name="PickerFullModeItemTemplate">
<StackPanel Orientation="Horizontal" Margin="16 21 0 20" Background="Orange" Width="110" Height="110" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{WHAT TO TYPE HERE?}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" FontSize="36"/>
</StackPanel>
</DataTemplate>
I populate my listpicker by setting the itemsource in C# like this
foreach (Item i in weight)
{
sourceInput.Add(i.name);
}
}
InputSelector.ItemsSource = sourceInput;
This leaves me with an itemsource list only containing strings, then i dont know how to bind the text for each item. I read some post on how to do it when the itemsource list is in this format
source.Add(new Cities() { Name = "Mexico", Country = "MX", Language = "Spanish" });
this.listPicker.ItemsSource = source;
and then the xaml part is something like this
<TextBlock Text="{Binding Name}"/>
any help would be greatly appreciated :)
UPDATE
i found the correct binding for binding to the sourceitems.
<TextBlock Text="{Binding BindsDirectlyToSource=True}"/>
Looks like thats the way to go, then the source items get binded to the textblock
You should be adding objects of type Cities to your sourceInput collection.
Typing Text="{Binding Name}" is correct.
Most likely your Cities class just doesn't implement the INotifyPropertyChanged interface. You should notify the UI each time you update the Name and other properties you have bound your UI elements to.
<TextBlock Text="{Binding Name}"/>
it is cool but for the listpicker there is also DisplayMemberPath property so,
on listpicker add :
DisplayMemberPath="Name"
For most of you, this might be an easy question, but I am a C# beginner (coming from VB) and would like to progam a Windows Phone App.
The question is: How can I access the TextBlock "LineOne" from code to change its width? For the page title, it works perfect with this (on orientation change):
this.PageTitle.Text = "Portrait";
However, something like this:
this.LineOne.width= "50";
won't work.
Why?
My XAML looks like this (almost the default data bound app from Visual Studio Express):
<!--TitlePanel -->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="PageTitle" Text="Bundesliga" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel -->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="ListboxPanel" Margin="0,0,0,17" Width="432" Orientation="Horizontal">
<TextBlock x:Name="LineOne" Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" Width="40" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Thanks for your help!
You have to access the TextBlocks inside the listbox.
Something like:
TextBlock textblock = ListboxPanel.Items[index] as TextBlock;
textblock.Width = 50
IEnumerable<TextBlock> listtb = ListboxPanel.Items.TypeOf<TextBlock>();
The name can't be resolved as belonging to this as it belongs to the datatemplate. You can't refer to an item within a template (from outside that template) as there could be multiple items with that name and names must be unique.
If you are trying to change the style of the selected item you will likely find a better solution to be to use different visual states to represent this.
If you are trying to access a property which relates to the bound viewmodel you can cast the sender to the type of the viewmodel and access it's properties directly.