I have a strange problem with a combobox in a WinRT application running under Win 8 Release Preview. Here is a code snippet :
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Name, Mode=TwoWay}" VerticalAlignment="Center"/>
<ComboBox Grid.Column="1" ItemsSource="{Binding Source={StaticResource evtTypeRes}}" SelectedValuePath="ID" DisplayMemberPath="Name" SelectedValue="{Binding EventTypeID, Mode=TwoWay}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
The ListView is backed by ObservableCollection list and the items implement INotifyPropertyChanged. The problem is that when I change the value of a combobox in the screen the value is changed not only for the particular row, but every row (the setter for the property is called on every object form the collection). This is not the case with the text box. What could be the reason for this strange behavior ?
Thanks in advance
I found the purpose of the IsSynchronizedWithCurrentItem attribute : value False solved my problem.
Related
I have WinRT application with following GridView:
<GridView x:Name="RouteGrid"
ItemsSource="{Binding Routes}"
SelectedItem="{Binding SelectedRoute,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"
SelectionMode="Single">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="300" Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" Text="{Binding TermText}" />
<TextBlock Grid.Column="1" Text="{Binding ConnectionObjects.Count}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I want to show a button instead of the second textblock when ever the item is selected because I want to allow my users to navigate to another view when they've selected.
I would like to do it in pure XAML because that is for me the cleanest way but I have no idea how to bind to the IsSelected property of the GridViewItem.
In WPF I would bind the Visibility property of the TextBlock and the button with a BooleanToVisibilityConverter and RelativeSource to the AncestorType GridViewItem and its property but that's not working because WinRT does not know AncestorType :(
Thanks for help.
In my app, i have a longlistselector and i set the "DataContext = list" in the event PhoneApplicationPage_Loaded. Inside this longlistselector, i have this code:
<DataTemplate>
<StackPanel Margin="5,10" >
<Border BorderThickness="1" CornerRadius="5">
<Grid Margin="10,8" Tap="Grid_Tap_1" x:Name="gridPasta" Tag="{Binding Id_pasta}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" HorizontalAlignment="Stretch" Text="{Binding Nm_pasta}" Grid.Column="0" TextWrapping="Wrap" VerticalAlignment="Top" TextTrimming="WordEllipsis" FontSize="24"/>
<Border Background="#E3F4FF" Grid.Column="1" CornerRadius="100">
<TextBlock Foreground="Black" Text="{Binding Qtde_pasta}" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20"/>
</Border>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
I want to set the background color of the specific Grid after i fill the LLS. I have search on internet about access LLS childs, but, nothing works. i have tried this link (Loop through longlistselector to get checkbox in itemtemplate), but the "SearchElement" not find the specific Grid.
My question is, how can i access this specific Grid after i fill the LLS?
Note: The specific Grid is known comparing the "Id_pasta" of the Grid.
Thanks for help.
You could add simple bool property (and implement PropertyChanged) to the class you're using for this datatemplate, bind it as background to the grid and use converter to convert it to desired backgroundcolor if true or false.
This is what I am doing.
UserControl.xaml
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<phone:LongListSelector
Name="MainList"
ItemsSource="{Binding}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<views:PostView
DataContext="{Binding ElementName=MainList, Path=ItemsSource}">
</views:PostView>
</StackPanel>
</DataPanel>
I want controls inside my PostView to be bound with properties of Current ItemsSource element. But whats happening is, say I have List of 5 objects set as ItemsSource, every element in my Post view gets 5 values.
So I am getting 25 PostViews initialized, 5 per ItemsSource object, instead of 1.
Here is my PostView.xaml is it helps
PostView.xaml
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ItemsControl
ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=User.Username, Mode=OneWay}" />
</StackPanel>
User is an Object property in the model I am binding to.
How can I fix it?
You are binding the user control to the whole collection, instead of just one item. Instead if DataContext="{Binding ElementName=MainList, Path=ItemsSource}" just use DataContext="{Binding ElementName=MainList, Path=SelectedItem}" or just DataContext="{Binding}" should work.
Took help from this post to set up a dependency field for my data in PostView.xaml.cs and set it up from UserControl.xaml
I finally got my pivot control to work using MVVM in a wp8 app but I still have a question in regards to binding as thought as it works, and I could accept it as is, I'm not happy with the outcome and I'm trying to understand why this is happening. My DataContext, MainViewModel, contains multiple other ViewModels.
Scenario 1:
If I define the DataContext in the Grid (layout), and I assign the itemsSource for the pivot headers to QuickSearchTabs ViewModel and this get built ok but the listbox I have defined inside the pivotitem doesn't which is assigned the QuickSearchButtons ViewModel doesn't get built. Here is the xaml code:
<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{StaticResource MainViewModel}" >
<phone:Pivot x:Name="Pivot" ItemsSource="{Binding QuickSearchTabs}" FontSize="{StaticResource PhoneFontSizeSmall}" SelectedIndex="{Binding SelectedSearchTabIndex, Mode=TwoWay}">
<phone:Pivot.Title>
<TextBlock Text="My Search Options" />
</phone:Pivot.Title>
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<ContentControl Content="{Binding Name}" />
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding QuickSearchButtons}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="{Binding Name}" Grid.Row="0">
</Button>
<TextBlock Text="{Binding Description}" Grid.Row="1">
</TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</Grid>
Scenario 2:
If I define the DataContext in the Grid (layout) and define the same DataContext within the listbox tags, it will build my header and my listbox BUT it will call my viewModel which is assigned to the ItemsSource of the listbox, multiple times. To be exact, it will call it the same number of time as the number of pivots I have. Here is the xaml code:
<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{StaticResource CriteriaViewModel}" >
<phone:Pivot x:Name="Pivot" ItemsSource="{Binding QuickSearchTabs}" SelectedIndex="{Binding SelectedSearchTabIndex, Mode=TwoWay}" >
<phone:Pivot.Title>
<TextBlock Text="My Search Options" />
</phone:Pivot.Title>
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<ContentControl Content="{Binding Name}"/>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding QuickSearchButtons}" DataContext="{StaticResource CriteriaViewModel}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="{Binding Name}" Grid.Row="0">
</Button>
<TextBlock Text="{Binding Description}" Grid.Row="1">
</TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</Grid>
As mentioned, this works, and it's not affecting me in anyway as the correct data is always displayed.
I can somehow see what's happening but why on earth would the ItemsSource be set for each of the defined pivot headers. Surely, the only important one is the one coming into visibility!
I don't know if Pivots are suppose to be used the way I'm using them. It seems, from what I've seen so far that normally a view is assigned to each PivotItem. This is not how I want my solution to work!
I just want numerous headers which are used to groups things in a specific manner and whatever is displayed under each is build dynamically but on the same view i.e. list of buttons and label.
Any ideas on how I could get scenario 1) to work and if I'm stuck with scenario 2, how to stop it from being triggered based on the number of pivot header items?
Thanks.
Problem solved!
The QuickSearchTabs was an observable collection of QuickSearchTab when it should have been an observable collection of ViewModel i.e. QuickSearchTabViewModel and within this viewModel, it will load the observable collection of relevant QuickSearchButtons for each of the tab.
Having a QuickSearchTabViewModel provides more flexibility and it will allow access to the current tab (header), and other relevant properties including everything maintain within each of these tabs such as, in my case the buttons.
Hope this helps.
I am trying to bind a Listbox ItemSource to a collection of multiple Lists. i.e.
List PersonCollection
List Person
List Collection
Now I need to show items from both of these list. In wpf you could use HierarchicalDataTemplate i believe, but not sure how I can do it in windows phone 7. Tried with Blend and it generates the following data template.
<DataTemplate x:Key="PersonDataTemplate">
<Grid>
<StackPanel Margin="0,0,1,0" Orientation="Vertical" VerticalAlignment="Top">
<TextBlock Margin="0,0,1,0" TextWrapping="Wrap" Text="{Binding Person[0].Name}" d:LayoutOverrides="Width"/>
<TextBlock Margin="0,0,1,0" TextWrapping="Wrap" Text="{Binding Collection[0].Total}" d:LayoutOverrides="Width"/>
</StackPanel>
</Grid>
</DataTemplate>
<ListBox Height="300" x:Name="personList" ItemsSource="{Binding PersonCollection}" Margin="10,0" ItemTemplate="{StaticResource PersonDataTemplate}"/>
Is there another way I can do this? I have tried to set the DataContext of Textbox in DataTemplate to individual arrays but did not seem to work. Cant find anything similar on the net apart from the confirmation that HierarchicalDataTemplate is not supported in Windows Phone 7.
I have other ways to do but none elegant..
Thanks in advance.
Regards
I think your scenario can be solved with two level ListBoxes instead of Tree-Heirarchy. See if the below trick works. Now you will see Both of your inner collection side by side in a Grid which are two other ItemsControls(Or you can have ListBoxes)
<DataTemplate x:Key="PersonCollextionItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding ListPerson}" ItemTemplate="{StaticResource Templ1}" Grid.Column="0"/>
<ItemsControl ItemsSource="{Binding ListCollection}" ItemTemplate="{StaticResource Templ2}" Grid.Column="1"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="Templ1">
<TextBlock Margin="0,0,1,0" Text="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="Templ2">
<TextBlock Margin="0,0,1,0" Text="{Binding Total}" />
</DataTemplate>
<ListBox Height="300" x:Name="personList" ItemsSource="{Binding PersonCollection}" Margin="10,0" ItemTemplate="{StaticResource PersonCollextionItem}"/>