In my Windows store app there is a list view which is using an item source to get data. It looks like this:
<ListView x:Name="lsvLinks" IsItemClickEnabled="True"
SelectionMode="Single"
ItemsSource="{Binding Source={StaticResource cvs2}}" ItemClick="lsvLinks_ItemClick" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" HorizontalChildrenAlignment="left"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="-7.5"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width="340" Height="32" Background="#FFBE9CDE" HorizontalAlignment="Left">
<StackPanel Width="255" VerticalAlignment="Center" Margin="15,0,0,0">
<TextBlock Text="{Binding Link}" Foreground="{Binding Color}" FontSize="15" Margin="0,3,0,0" FontWeight="Normal" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Width="50" VerticalAlignment="Center" Margin="0,0,0,0">
<Button x:Name="btnRemove" Width="30" Height="30" Margin="20,0,0,0" ToolTipService.ToolTip="Remove" Click="btnRemove_click">
<Button.Template>
<ControlTemplate>
<Image Source="Assets/cancel.png" Width="30" Height="30"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My C# code
try {
IEnumerable < linkTable > obsCollection = (IEnumerable < linkTable > ) await webservice.getLinksStudentAsync(1);
linkList = new List < linkTable > (obsCollection);
int count = 1;
foreach(linkTable linkL in linkList) {
if (linkL.status.Equals("yes")) {
links.Add(new Collection {
ID = count, Link = linkL.link, Type = "Accept", Color = "green", BackColor = "#FFA27BC7"
});
} else if (linkL.status.Equals("no")) {
links.Add(new Collection {
ID = count, Link = linkL.link, Type = "Reject", Color = "Red", BackColor = "#FFA27BC7"
});
} else {
links.Add(new Collection {
ID = count, Link = linkL.link, Type = "Pending", Color = "White", BackColor = "#FFA27BC7"
});
}
count++;
}
cvs2.Source = links;
}
When a user selects an item in the listview, I need to retrieve its ID. But I don't understand how to do that. Can anyone tell me how to do that?
You'll need to add a SelectionChanged event to the ListView and implement it.
public void ItemSelected(object sender, SelectionChangedEventArgs args)
{
var item= lsvLinks.SelectedItem as Collection;
int ID = item.ID;
}
On your ListView you could add the event as below.
<ListView x:Name="lsvLinks" IsItemClickEnabled="True" SelectionMode="Single" ItemsSource="{Binding Source={StaticResource cvs2}}" SelectionChanged="ItemSelected" >
Related
I have a window with version text boxes, buttons, and a ListBoxthat expands and contracts. Each ListBox item has multiple text boxes. I am trying to find a way to tab navigate from outside of the the ListBoxto the first TextBox in the first item for the ListBox. I can get it to navigate to the ListBox itself and if I hit the down arrow key it will select the first item but that is clumsy. I need it to tab directly from something outside the ListBox to something inside the ListBox.
Below is some of the XAML I use for the ListBox.
<ListBox x:Name="add_users_listbox" Margin="2,116,-8,0" BorderThickness="0" Height="322" Padding="0,0,0,0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Top"
HorizontalAlignment="Center" VerticalAlignment="Top"
SelectionMode="Single"
IsTabStop="True"
TabIndex="1004"
Background="{x:Null}" BorderBrush="{x:Null}"
ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.CanContentScroll="False"
ItemsSource="{Binding Add_User_Binding}"
SelectedIndex="{Binding Add_User_Selected_Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ListBox.Resources>
<Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource ScrollBar_Rounded}"/>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource CustomListBoxItemStyle}"/>
<Style TargetType="{x:Type ListBox}" >
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="60" Background="Transparent"
HorizontalAlignment="Center" VerticalAlignment="Top">
<TextBox Height="26" Width="102" Padding="0,-1,0,1" Margin="2,2,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
FontFamily="Segoe UI" FontSize="16" FontWeight="Bold"
TextWrapping="NoWrap" IsReadOnlyCaretVisible="True" UndoLimit="10" AllowDrop="False" MaxLines="1"
TabIndex="{Binding First_TabIndex}"
MaxLength="20"
TextChanged="first_last_textbox_TextChanged"
PreviewTextInput="first_last_textbox_PreviewTextInput"
Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True}">
</TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Simply make your ListBox IsTabStop="False" and the LitBoxItemStyle too.
I added this setter to the ListBoxItemStyle: <Setter Property="IsTabStop" Value="False"/>
<ListBox x:Name="add_users_listbox" Grid.Row="1" BorderThickness="0" Height="322" Padding="0,0,0,0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Top"
HorizontalAlignment="Center" VerticalAlignment="Top"
SelectionMode="Single"
IsTabStop="False"
TabIndex="1004"
Background="{x:Null}" BorderBrush="{x:Null}"
ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.CanContentScroll="False"
ItemsSource="{Binding Add_User_Binding}"
SelectedIndex="{Binding Add_User_Selected_Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ListBox.Resources>
<Style TargetType="{x:Type ScrollBar} BasedOn="{StaticResource ScrollBar_Rounded}" "/>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource CustomListBoxItemStyle}">
<Setter Property="IsTabStop" Value="False"/>
</Style>
<Style TargetType="{x:Type ListBox}" >
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="60" Background="Transparent"
HorizontalAlignment="Center" VerticalAlignment="Top">
<TextBox Height="26" Width="102" Padding="0,-1,0,1" Margin="2,2,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
FontFamily="Segoe UI" FontSize="16" FontWeight="Bold"
TextWrapping="NoWrap" IsReadOnlyCaretVisible="True" UndoLimit="10" AllowDrop="False" MaxLines="1"
MaxLength="20"
TextChanged="first_last_textbox_TextChanged"
PreviewTextInput="first_last_textbox_PreviewTextInput"
Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
</TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So, this is likely NOT the ideal way to do this, but it works. First we add a bound tag to the TextBox within the DataTemplate
ItemsSource="{Binding ListBox_Item_Collection}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
Tag="{Binding Index}">
</TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
For simplicity I bound that tag to the corresponding index in the ItemSource collection.
int index = Add_User_Binding.Count;
ListBox_Item_Collection.Add(new SomeDataType()
{
Index = index,
The_Textbox = "Stuff in TextBox",
});
The next step is to add a KeyDown event in the user control that comes before this one. In that event we will find the element with that tag and then use the Dispatcher to focus it.
private void Preview_TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
{
string tag = "0";
IEnumerable<TextBox> elements = FindVisualChildren<TextBox>(this).Where(x => x.Tag != null && x.Tag.ToString() == tag);
foreach (TextBox element in elements)
{
FocusElement(element);
}
}
}
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
private void FocusElement(IInputElement element)
{
if (element != null)
{
Dispatcher.BeginInvoke
(System.Windows.Threading.DispatcherPriority.ContextIdle,
new Action(delegate ()
{
Keyboard.Focus(element);
}));
}
}
As you can see, lots of work for something that should be much simpler.
I want make a footer to my DataGrid using this method:
How do I add a footer row in a WPF datagrid?
But, i need to make this by code behind, and that's don't working.
I think it's because the binding of the grid can't find the column.
private DataGridColumn dgInsertCol(ref int idx, DataGridColumn dgc, tblEtatRecapColonne pCol, string pBinding = "") {
var dhHeadName = $"dgHead{pCol.Id}";
dgc.SetValue(NameProperty, dhHeadName);
dgc.HeaderTemplate = GetDtHeader(pCol, pBinding);
dgc.Width = new DataGridLength(1.0, (ckbSize.IsChecked.Value) ? DataGridLengthUnitType.Star : DataGridLengthUnitType.SizeToCells);
dgMain.Columns.Insert(idx++, dgc);
// Faire le footer associé
var t = new TextBlock() { Margin = new Thickness(5, 0, 0, 0), Text = pBinding, Background = new SolidColorBrush(Color.FromRgb(50, 100, 150)) };
var g = new Grid() { MinWidth = 10 };
g.SetBinding(Grid.WidthProperty, new Binding("ActualWidth") { ElementName = dhHeadName, Path=new PropertyPath("ActualWidth", null) }); // DataGridColumn
g.Children.Add(t);
pnlDgFooter.Children.Add(g);
return dgc;
}
<DataGrid Grid.Row="1" x:Name="dgMain" AutoGenerateColumns="False" SelectionUnit="FullRow" LoadingRow="dgMain_LoadingRow" MouseDown="dgMain_MouseDown" Sorting="dgMain_Sorting"
CanUserReorderColumns="False" CanUserResizeColumns="True" CanUserResizeRows="False" CanUserSortColumns="True" CanUserAddRows="False"
Style="{StaticResource dg}" RowStyle="{StaticResource dgRow}" CellStyle="{StaticResource dgCell}" ColumnHeaderStyle="{StaticResource dgColHeader}" RowHeaderStyle="{StaticResource dgRowHeader}"
ItemsSource="{Binding NotifyOnSourceUpdated=True, Source={StaticResource cvsElmts}}" HorizontalAlignment="Left">
<!--DataGrid.DataContext><Binding Source="{StaticResource tblUsers}"/></DataGrid.DataContext-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<mvvm:EventToCommand Command="{Binding SendCommand, Mode=OneWay}" CommandParameter="{Binding SelectedItem, ElementName=dgMain}" PassEventArgsToCommand="False"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" BorderThickness="1,1,1,5">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups under the top level. -->
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="LightBlue">
<TextBlock Text="{Binding Path=Name}" Foreground="Blue" Margin="30,0,0,0" Width="100"/>
<TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<StaticResource ResourceKey="rowBtnDetail"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="2" Name="pnlDgFooter" HorizontalAlignment="Left" Orientation="Horizontal" >
</StackPanel>
Why use ElementName at all? Set the Source of the Binding directly. Also, don't set Path twice, so either write
g.SetBinding(Grid.WidthProperty,
new Binding
{
Source = dgc,
Path = new PropertyPath("ActualWidth")
});
or
g.SetBinding(Grid.WidthProperty, new Binding("ActualWidth") { Source = dgc });
I have a ListView box containing TextBoxes that allow users to add and change the content. How do I verify that the content that is changed is not the same as any exiting one in C# behind?
Xaml:
<ListView
x:Name="_regionQueryListBox"
Width="122"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
DataContext="{Binding}"
IsSynchronizedWithCurrentItem="True"
Style="{StaticResource ListViewRegionSelectorStyle}"
ItemsSource="{Binding Path=Model}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionChanged="_regionQueryListBox_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Region" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
MaxLength="16"
Width="110"
Margin="-2,0,0,0"
Padding="-2,0,0,0"
Text="{Binding Path=RegionName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Yes, it is MVVM. I have a validation for adding same item and you can find the Model like below:
private void OnQueryCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
if (Model.Count == 0)
{
CurrentRegionViewModel = null;
}
if (args.Action == NotifyCollectionChangedAction.Add)
{
RegionQuery addedRegionQuery = args.NewItems.OfType<RegionQuery>().FirstOrDefault();
if (addedRegionQuery != null)
{
string name = addedRegionQuery.RegionName;
while (Model.Any(q => q.RegionName == name && q != addedRegionQuery))
{
name += "*";
}
addedRegionQuery.RegionName = name;
}
}
The standard GridApp template is as follows:
Variable Sized Grouped GridView template is as follows:
How to make a template for your application, so that it looks like this:
For example, this design in all applications Bing for windows 8:
Code for Variable Sized Grouped GridView template:
<UserControl.Resources>
<!-- Collection of grouped items displayed by this page -->
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding ItemGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
<DataTemplate x:Key="CustomTileItem">
<Grid >
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom" >
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</UserControl.Resources>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Grid.Column="1" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
<!-- Horizontal scrolling grid used in most view states -->
<ScrollViewer
x:Name="itemGridScrollViewer"
AutomationProperties.AutomationId="ItemGridScrollViewer"
Grid.Row="1"
Margin="0,-3,0,0"
Style="{StaticResource HorizontalScrollViewerStyle}">
<local:MyGridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Margin="116,0,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource CustomTileItem}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<local:MyGridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</local:MyGridView.ItemsPanel>
<local:MyGridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="1,0,0,6">
<Button
AutomationProperties.Name="Group Title"
Content="{Binding Title}"
Click="Header_Click"
Style="{StaticResource TextButtonStyle}"/>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemWidth="75" ItemHeight="150" Orientation="Vertical" Margin="0,0,80,0" MaximumRowsOrColumns="3"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</local:MyGridView.GroupStyle>
</local:MyGridView>
</ScrollViewer>
and:
public class MyGridView : GridView
{
private int rowVal;
private int colVal;
private Random _rand;
private List<Size> _sequence;
public MyGridView()
{
_rand = new Random();
_sequence = new List<Size> {
LayoutSizes.PrimaryItem,
LayoutSizes.SecondarySmallItem, LayoutSizes.SecondarySmallItem,
LayoutSizes.SecondarySmallItem,
LayoutSizes.SecondaryTallItem,
LayoutSizes.OtherSmallItem, LayoutSizes.OtherSmallItem, LayoutSizes.OtherSmallItem
};
}
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
SampleDataItem dataItem = item as SampleDataItem;
int index = -1;
if (dataItem != null)
{
index = dataItem.Group.Items.IndexOf(dataItem);
}
if (index >= 0 && index < _sequence.Count)
{
colVal = (int)_sequence[index].Width;
rowVal = (int)_sequence[index].Height;
}
else
{
colVal = (int)LayoutSizes.OtherSmallItem.Width;
rowVal = (int)LayoutSizes.OtherSmallItem.Height;
}
VariableSizedWrapGrid.SetRowSpan(element as UIElement, rowVal);
VariableSizedWrapGrid.SetColumnSpan(element as UIElement, colVal);
}
}
public static class LayoutSizes
{
public static Size PrimaryItem = new Size(6, 2);
public static Size SecondarySmallItem = new Size(3, 1);
public static Size SecondaryTallItem = new Size(3, 2);
public static Size OtherSmallItem = new Size(2, 1);
}
For example with "Variable Sized Grouped GridView template", we can combine the rows or columns, and how to set the first element height = "auto", and all other elements that have different widths and heights, but grouped as "Variable Sized Grouped GridView template"?
View this post:
http://blogs.msdn.com/b/synergist/archive/2012/09/25/windows-store-app-xaml-gridview-with-variable-templates.aspx
I think this is what you need.
I have the following templete
<ControlTemplate x:Key="tmpl_btn_TecnicianModeMenu" TargetType="{x:Type ListBoxItem}">
<Grid Opacity="1" d:LayoutOverrides="Width, Height">
<Border
x:Name="Border"
CornerRadius="0"
BorderThickness="0" Height="Auto" Margin="0" Background="White">
<StackPanel Name="stackPanel" Height="Auto" Margin="0" Orientation="Horizontal" >
<Button x:Name="button" Style="{DynamicResource ButtonListBoxItem}" Margin="5,5,5,5" Width="120" Height="Auto" BorderThickness="0" >
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="בצע" Margin="12,0" VerticalAlignment="Center" HorizontalAlignment="Stretch" Style="{DynamicResource tb_Desc}"/>
</Button>
<StackPanel Height="Auto" Margin="0" Orientation="Horizontal" >
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center" x:Name ="LB_Result" Text="LB_Result" Style="{DynamicResource LB_AreaTitle_Balance}" Margin="5,5,5,5" d:LayoutOverrides="Height" />
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center" x:Name ="LB_OK" Text="LB_OK" Style="{DynamicResource LB_AreaTitle_Balance}" Margin="5,5,5,5" d:LayoutOverrides="Height" />
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center" x:Name ="LB_TchName" Text="LB_TchName" Style="{DynamicResource LB_AreaTitle_Balance}" Margin="5,5,5,5"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center" x:Name ="LB_Date" Text="LB_Date" Style="{DynamicResource LB_AreaTitle_Balance}" Margin="5,5,5,5" d:LayoutOverrides="Height"/>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center" x:Name ="LB_CheckName" Text="{TemplateBinding Tag}" Style="{DynamicResource LB_AreaTitle_Balance}" Margin="5,5,5,5"/>
</StackPanel>
</StackPanel>
</Border>
<Border x:Name="Divide" BorderBrush="Gray" BorderThickness="0,0.5" Height="140" Width="Auto" Margin="18.5,0" VerticalAlignment="Bottom"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
** I have list box of such items.
I want to bind it to an observable list.
the problem is that the previus programer added items to the list like this:**
private void AddButtonToList(String LB_CheckName, String LB_Date, String LB_TchName, String LB_OK, String LB_Result, enmTechMode_Check enmCheck )
{
try
{
//create item
ListBoxItem item2 = new ListBoxItem();
//set template
item2.SetResourceReference(ListBoxItem.TemplateProperty, "tmpl_btn_TecnicianModeMenu");
item2.ApplyTemplate();
item2.Height = 45;
TextBlock txt1 = (TextBlock)item2.Template.FindName("LB_CheckName", item2);
txt1.Text = LB_CheckName;
txt1 = (TextBlock)item2.Template.FindName("LB_Date", item2);
txt1.Text = LB_Date;
txt1 = (TextBlock)item2.Template.FindName("LB_TchName", item2);
txt1.Text = LB_TchName;
txt1 = (TextBlock)item2.Template.FindName("LB_OK", item2);
txt1.Text = LB_OK;
txt1 = (TextBlock)item2.Template.FindName("LB_Result", item2);
txt1.Text = LB_Result;
Button bt = (Button)item2.Template.FindName("button", item2);
bt.SetResourceReference(Button.StyleProperty, "ButtonListBoxItem");
bt.ApplyTemplate();
bt.Click += new RoutedEventHandler(Item_Selected);
//set tag
bt.Tag = enmCheck;
//add to list
StackPanel sp = (StackPanel)ListBoxData.FindName("stackPanel");
item2.Tag = enmCheck;
sp.Children.Add(item2);
}
catch (Exception exp)
{
}
}
and I have no clue how to fix this
I assume theres suppose to be a use of a convertor? please provide me a direction
I assume the observable list suppose to be of structs. but how convert those to items in the temples format?
In a template you would usually bind to properties of the data object. If for example you have the data class below with a Result property
public class MyData
{
public string Result { get; set; }
...
}
you would bind like this:
<TextBlock Text="{Binding Path=Result}" ... />
Then you would not manually add ListBoxItems, but instead add data objects to the ObservableCollection, that the ItemsSource property of the ListBox is bound to:
myDataObjects.Add(
new MyData
{
Result = "A Result"
...
});
where myDataObjects is an ObservableCollection<MyData>.
In case you would need to get the UI updated when a data object changes which is already contained in the ObservableCollection, class MyData would need to implement INotifyPropertyChanged.