WP7 LongListSelector ItemsSource Databinding Issue - windows-phone-7

I am trying to implement the LongListSelector in a new WP7 application. The LongListSelector exists in a UserControl bound to an MVVMLight view model. I get the following error when I try to load the UserControl:
System.ArgumentException was unhandled
Message=The parameter is incorrect.
StackTrace:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper obj, DependencyProperty property, Double d)
at System.Windows.DependencyObject.SetValue(DependencyProperty property, Double d)
at System.Windows.FrameworkElement.set_Width(Double value)
at Microsoft.Phone.Controls.LongListSelector.GetAndAddElementFor(ItemTuple tuple)
at Microsoft.Phone.Controls.LongListSelector.Balance()
at Microsoft.Phone.Controls.LongListSelector.EnsureData()
at Microsoft.Phone.Controls.LongListSelector.LongListSelector_Loaded(Object sender, RoutedEventArgs e)
at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)
I have been able to narrow down the problem to the Items in my binding source, however I cannot see what the problem is.
Here is the XAML from my UserControl:
<UserControl x:Class="BTT.PinPointTime.WinPhone.Views.TaskSelectionControl"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480"
d:DesignWidth="480"
DataContext="{Binding Source={StaticResource Locator}, Path=TaskSelection}">
<UserControl.Resources>
<DataTemplate x:Key="itemTemplate">
<StackPanel Grid.Column="1"
VerticalAlignment="Top">
<TextBlock Text="{Binding Name}"
FontSize="26"
Margin="12,-12,12,6" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="groupHeaderTemplate">
<Border Background="YellowGreen"
Margin="6">
<TextBlock Text="{Binding Title}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="groupItemTemplate">
<Border Background="Pink"
Margin="6">
<TextBlock Text="{Binding Title}" />
</Border>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<toolkit:LongListSelector Grid.Row="1"
Background="Red"
ItemsSource="{Binding GroupedTasks}"
GroupItemTemplate="{StaticResource groupItemTemplate}"
ItemTemplate="{StaticResource itemTemplate}"
GroupHeaderTemplate="{StaticResource groupHeaderTemplate}">
<toolkit:LongListSelector.GroupItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</toolkit:LongListSelector.GroupItemsPanel>
</toolkit:LongListSelector>
</Grid>
</Grid>
And here is the code that I am using to populate the GroupedTasks property in my view model (it is declared as ObservableCollection> GroupedTasks):
private void LoadData()
{
if (App.Database.Query<Task, Guid>().Count() > 0)
{
GroupedTasks.Clear();
var tasks = (from t in App.Database.Query<Task, Guid>().ToList() select t.LazyValue.Value);
var groupedTasks = from t in tasks
group t by t.FullParentString into t1
orderby t1.Key
//select new Group<Task>(t1.Key, t1);
select new Group<Task>(t1.Key);
foreach (Group<Task> o in groupedTasks)
{
GroupedTasks.Add(o);
}
foreach (Group<Task> g in GroupedTasks)
{
var currentTasks = (from t in tasks where t.FullParentString == g.Title select t);
foreach (Task t in currentTasks)
{
g.Add(t);
}
}
}
_isDataLoaded = true;
}
and finally here is the declaration of my Group class:
public class Group<T> : ObservableCollection<T>
{
public string Title
{
get;
set;
}
public bool HasItems
{
get
{
return Count != 0;
}
private set
{
}
}
public Group(string name)
{
this.Title = name;
}
}
I did originally implement this as a simple IEnumerable as per the turorial on Windows Phone Geek. However that gave me exactly the same error.
I do not get any binding errors, however there is nothing that I can see that will enable me to track down the source of the problem.

The answer is found here: http://silverlight.codeplex.com/workitem/7707. Basically add a width and height to the LongListSelector.

Related

How do I bind to a validation rule in XAML

I am following the example given here:
https://social.technet.microsoft.com/wiki/contents/articles/31422.wpf-passing-a-data-bound-value-to-a-validation-rule.aspx
I get the exception at the following line in my DataTemplateSelector:
return element.FindResource("MinParameterDataTemplateThin") as DataTemplate;
"Unexpected record in Baml stream. Trying to add to MaximumValueValidation which is not a collection or has a TypeConverter."
Code:
public class BindingProxy : System.Windows.Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get => (object)GetValue(DataProperty);
set => SetValue(DataProperty, value);
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
}
public class MaxValueWrapper : DependencyObject
{
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(double),
typeof(MaxValueWrapper), new FrameworkPropertyMetadata(double.MaxValue));
public int MaxValue
{
get => (int)GetValue(MaxValueProperty);
set => SetValue(MaxValueProperty, value);
}
}
public class MaximumValueValidation : ValidationRule
{
public MaxValueWrapper MaxValueWrapper { get; set; }
/// <summary>
/// validate whether the input value is in range
/// </summary>
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
try
{
if (value != null && ((string)value).Length > 0)
{
double userInput = double.Parse((string)value);
if (userInput > MaxValueWrapper.MaxValue)
return new ValidationResult(false,
"Please enter a value <= Max " + MaxValueWrapper.MaxValue);
}
}
catch (Exception e)
{
return new ValidationResult(false, $"Invalid characters or {e.Message}");
}
return ValidationResult.ValidResult;
}
}
XAML:
<DataTemplate x:Key="MinParameterDataTemplateThin">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DisplayName, StringFormat='{}{0}:'}" Grid.Column="0" Margin="10,5,5,10" VerticalAlignment="Top" TextWrapping="Wrap"
Visibility="{Binding Visibility}" ToolTipService.ShowDuration="20000">
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={x:Static RelativeSource.Self}}">
<TextBlock Text="{Binding Description}"/>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBox Margin="5" Width="50" VerticalAlignment="Top"
Visibility="{Binding Visibility}" IsEnabled="{Binding IsEnabled}">
<i:Interaction.Behaviors>
<utilities:SelectTextOfTextBox/>
</i:Interaction.Behaviors>
<TextBox.Resources>
<validations:BindingProxy x:Key="proxy" Data="{Binding}"/>
</TextBox.Resources>
<TextBox.Text>
<Binding Path="{Binding DefaultValue, StringFormat=N2}" Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnExceptions="True"
NotifyOnValidationError="True"
ValidatesOnNotifyDataErrors="True">
<Binding.ValidationRules>
<validations:MaximumValueValidation ValidatesOnTargetUpdated="True">
<validations:MaximumValueValidation.MaxValueWrapper>
<validations:MaxValueWrapper MaxValue="{Binding Data.MaxValue, Source={StaticResource proxy}}"/>
</validations:MaximumValueValidation.MaxValueWrapper>
</validations:MaximumValueValidation>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Text="{Binding UnitSymbol}" Margin="5" VerticalAlignment="Top" Visibility="{Binding Visibility}"/>
</StackPanel>
</Grid>
</DataTemplate>
I have several working DataTemplates like this one, but they do not use validation rules with the TextBox. Perhaps I am not following the wiki example correctly, but I am not seeing the problem, and I don't understand the exception.
EDIT:
After staring at the exception message, it occurs to me that the "outer" DataTemplate might be relevant, but I cannot be sure. The DataTemplate above is for a WorkflowParameter object, which is part of a Collection nested in a parent WorkflowParameter object. The DataTemplate for this parent is:
<DataTemplate x:Key="GroupedInversionParameterDataTemplate">
<Grid Visibility="{Binding Visibility}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="800"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DisplayName, StringFormat='{}{0}:'}" Grid.Column="0" Margin="5" VerticalAlignment="Top" TextWrapping="Wrap"
Visibility="{Binding Visibility}" ToolTipService.ShowDuration="20000">
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={x:Static RelativeSource.Self}}">
<TextBlock Text="{Binding Description}"/>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
<ItemsControl ItemsSource="{Binding GroupedWorkflowParameters}" Grid.Column="1"
ItemTemplateSelector="{StaticResource WorkflowParameterTemplateSelector}"
IsTabStop="False">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Visibility" Value="{Binding Visibility}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</DataTemplate>
The mention of trying to add a collection, in the exception message, made me think that the ItemsControl in this outer template could be a problem. I would not expect it to be an issue, but maybe I am missing something.
I though the problem as with the validation XAML, so I commented it out and found there was still an exception. This snippet of XAML:
<Binding Path="{Binding DefaultValue, StringFormat=N2}"
had to change to
<Binding Path="DefaultValue" StringFormat="N2"

How can I get control in DataTemplate?

So, I have a code:
<tool:LongListSelector x:Name="citiesListGropus" Background="Transparent"
ItemTemplate="{StaticResource citiesItemTemplate}"
GroupHeaderTemplate="{StaticResource groupHeaderTemplate}"
GroupItemTemplate="{StaticResource groupItemTemplate}" Height="468" Margin="0,68,0,0">
<tool:LongListSelector.GroupItemsPanel>
<ItemsPanelTemplate>
<tool:WrapPanel/>
</ItemsPanelTemplate>
</tool:LongListSelector.GroupItemsPanel>
</tool:LongListSelector>
And have a DataTemplate:
<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
<Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName">
<TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
</Border>
</DataTemplate>
How can I change a property Visibility of Border in DataTemplate ? I want to hide DataTemplate. But I can't bind my data to a property such as TextBlock Text="{Binding Title}", because I make binding data once, then I need to change some properties after data binding.
Any Ideas?
UPDATE 1
So, my main goal is filter the list of cities. I want to filter them by name.
My algorithm:
1) I get data from WebService.
2) Load my ViewModel
if (!App.CitiesViewModel.IsDataLoaded)
{
App.CitiesViewModel.LoadData(serviceResponse.Result);
}
3) Group the cities by name. My code like this code.
This is important, especially for LongListSeletstor I have to use templates.
Ok, my data ready. Now I do not need a web service.
<!-- The template for city items -->
<DataTemplate x:Key="citiesItemTemplate">
<StackPanel Name="PlacePanel"
Orientation="Horizontal" Margin="0,0,0,17"
Tag="{Binding Id}" Visibility="{Binding IsVisibility}">
<Image Height="75" Width="75" HorizontalAlignment="Left" Margin="12,0,9,0" Name="Image" Stretch="Fill" VerticalAlignment="Top" Source="{Binding Image}"/>
<StackPanel Width="311">
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
I have TextBox, when I type name of a city - unnecessary cities hide. I can use data binding and INotifyPropertyChanged, so I can hide cities.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox name = (TextBox)sender;
foreach(var place in App.CitiesViewModel.Items
.Where(city => (city.Name.Contains(name.Text)) && (city.IsShow == true)))
{
city.IsVisibility = Visibility.Visible;
}
foreach (var city in App.CitiesViewModel.Items
.Where(city => !city.Name.Contains(name.Text)))
{
city.IsVisibility = Visibility.Collapsed;
}
}
But I have some problems, I can't hide this DataTemplate when I search cities:
<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
<Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName">
<TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
</Border>
</DataTemplate>
When I type name of a cities I want hide GroupHeaderTemplate. When TextBox lost focus show GroupHeaderTemplate.
I borrowed this picture here.
Update 2
My mistake was that I did not use PropertyChangedEventHandler. After adding this to GroupCity property and implementing an interface INotifyPropertyChanged I can change property Data Template after data binding.
private IList<Group<City>> citiesCollectionGroup;
var cityByName = from city in App.ViewModel.Items
group city by Convert.ToString(City.Name[0]).ToLower()
into c orderby c.Key select new
GroupCity<CitiesViewModel>(Convert.ToString(c.Key[0]).ToLower(), c);
citiesCollectionGroup = cityByName.ToList();
this.citiesListGropus.ItemsSource = citiesCollectionGroup;
public class GroupCity<T> : IEnumerable<T>, INotifyPropertyChanged
{
public GroupCity(string name, IEnumerable<T> items)
{
this.Title = name;
this.IsVisibility = Visibility.Visible;
this.Items = new List<T>(items);
}
public override bool Equals(object obj)
{
GroupCity<T> that = obj as GroupCity<T>;
return (that != null) && (this.Title.Equals(that.Title));
}
public string Title
{
get;
set;
}
private Visibility _isVisibility;
public Visibility IsVisibility
{
get
{
return _isVisibility;
}
set
{
_isVisibility = value;
NotifyPropertyChanged("IsVisibility");
}
}
public IList<T> Items
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return this.Items.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.Items.GetEnumerator();
}
#endregion
}
Xaml code:
<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
<Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName" Visibility="{Binding IsVisibility}">
<TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
</Border>
</DataTemplate>
Now we can change Visibility groupHeaderTemplate.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
foreach (GroupCity<CitiesViewModel> city in citiesCollectionGroup)
{
city.IsVisibility = Visibility.Collapsed;
}
//
}
private void SearchText_LostFocus(object sender, RoutedEventArgs e)
{
foreach (GroupCity<CitiesViewModel> city in citiesCollectionGroup)
{
city.IsVisibility = Visibility.Visible;
}
//
}
You can write your own simple DataTemplateSelector to do this. Check this out for more information.
With "How can I change a property Visibility of Border in DataTemplate ? I want to hide DataTemplate. " I understand that you want to change the visibility of an item based on a property, see example below.
(If the code below isn't quite the solution you are looking for please provide some more information about what you are trying to achieve. Re-reading your question and the comments I got on this example I doubt this is what you want to do, but I don't want to guess so I'm simply answering my interpretation of your question).
With bindings you can:
Bind the visibility property directly to a a property of type Visibility (example with listbox and Person1)
Bind the Visibility property to a boolean property, and use a converter to convert that to the Visibility type (listbox2 and Person2 + BoolToVis class).
There are more ways, but this are the two most simple to implement in my opinion.¨
result of code below:
View:
<phone:PhoneApplicationPage
x:Class="VisibilityWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
xmlns:VisibilityWP="clr-namespace:VisibilityWP"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.Resources>
<VisibilityWP:BoolToVis x:Key="BooleanToVisibilityConverter" />
</Grid.Resources>
<StackPanel>
<ListBox x:Name="listBox" Height="300">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Width="200" Visibility="{Binding Visibility}" Background="Blue">
<TextBlock Text="{Binding Name}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="listBox2" Height="300">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Width="200" Visibility="{Binding ShowBorder, Converter={StaticResource BooleanToVisibilityConverter}}" Background="Red">
<TextBlock Text="{Binding Name}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</Grid>
Code behind:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
namespace VisibilityWP
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
DataContext = this;
listBox.ItemsSource = new List<Person1>
{
new Person1 {Name = "Iris", Visibility = Visibility.Visible},
new Person1 {Name = "Somebody", Visibility = Visibility.Collapsed},
new Person1 {Name = "Peter", Visibility = Visibility.Visible},
};
listBox2.ItemsSource = new List<Person2>
{
new Person2 {Name = "Iris", ShowBorder = true},
new Person2 {Name = "Mia", ShowBorder = true},
new Person2 {Name = "Somebody", ShowBorder = false}
};
}
}
public class Person1
{
public string Name { get; set; }
public Visibility Visibility { get; set; }
}
public class Person2
{
public string Name { get; set; }
public bool ShowBorder { get; set; }
}
public sealed class BoolToVis : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value is Visibility && (Visibility)value == Visibility.Visible;
}
}
}

Parsing an XML generated by REST for WP7

I'm trying to develop a simple WP7 app that queries a REST feed which produces a XML file. Depending on the query, the feed can generate many different XML files, but I am having problems with the most basic one.
The XML I am trying to display in a ListBox looks like;
<subsonic-response status="ok" version="1.1.1">
</subsonic-response>
or
<subsonic-response status="ok" version="1.1.1">
<license valid="true" email="foo#bar.com" key="ABC123DEF" date="2009-09-03T14:46:43"/>
</subsonic-response>
I've tried following several examples from MSDN and other source but I can't seem to wrap my head around it. The URL that I'm using works because it displays the correct information when entered into a browser, but for some reason isn't displayed in the ListBox.
Here is the code I am currently using;
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Xml.Linq;
namespace RESTTest
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
string requestString =
"http://WEBSITE/rest/{0}.view?u=USERNAME&p=PASSWORD&v=1.8.0&c=RestTest";
string UriNoAppId =
"http://WEBSITE/rest/{0}.view?u=USERNAME&p=PASSWORD&v=1.8.0&c=RestTest";
public MainPage()
{
InitializeComponent();
List<string> searchTopics = new List<string>() { "ping", "getLicense" };
comboBox1.DataContext = searchTopics;
comboBox1.SelectedIndex = 0;
// Create the WebClient and associate a handler with the OpenReadCompleted event.
wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
}
// Call the topic service at the Bing search site.
WebClient wc;
private void CallToWebService()
{
// Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
wc.OpenReadAsync(new Uri(String.Format(requestString, comboBox1.SelectedItem.ToString())));
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
XElement resultXml;
// You should always check to see if an error occurred. In this case, the application
// simply returns.
if (e.Error != null)
{
return;
}
else
{
XNamespace web = "http://subsonic.org/restapi";
try
{
resultXml = XElement.Load(e.Result);
// Search for the WebResult node and create a SearchResults object for each one.
var searchResults =
from result in resultXml.Descendants(web + "WebResult")
select new SearchResult
{
// Get the Title, Description and Url values.
Title = result.Element(web + "version").Value,
Url = result.Element(web + "status").Value
};
// Set the data context for the listbox to the results.
listBox1.DataContext = searchResults;
textBox1.DataContext = searchResults;
}
catch (System.Xml.XmlException ex)
{
textBlock2.Text = ex.Message;
}
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
CallToWebService();
}
// Update the textblock as the combo box selection changes.
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
uriTextBlock.DataContext = string.Format(UriNoAppId, e.AddedItems[0]);
}
}
// Simple class to hold the search results.
public class SearchResult
{
public string Title { get; set; }
public string Url { get; set; }
}
}
XAML
<phone:PhoneApplicationPage
x:Class="RESTTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="False">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem" >
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="LightGray"/>
</Style>
<Style x:Key="ComboBoxStyle" TargetType="ComboBox" >
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Gray"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="REST CLIENT"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Subsonic"
Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
Height="99" Width="453" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="12,139,12,0" Grid.RowSpan="2">
<Button Content="Search!" Height="89" HorizontalAlignment="Left"
Margin="264,140,0,0" Name="button1"
VerticalAlignment="Top" Width="189" Click="button1_Click" />
<ComboBox Height="50" Style="{StaticResource ComboBoxStyle}"
HorizontalAlignment="Left" Margin="6,159" Name="comboBox1"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
VerticalAlignment="Top" Width="235" ItemsSource="{Binding}"
SelectionChanged="comboBox1_SelectionChanged" />
<TextBlock Height="36" HorizontalAlignment="Left" Margin="12,120"
Name="textBlock2" Text="Search Topic:" VerticalAlignment="Top" width="121" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,1,0,0"
Name="textBlock3"
Text="URI:" VerticalAlignment="Top" />
<TextBlock Height="86" HorizontalAlignment="Left" Margin="6,28"
Name="uriTextBlock" TextWrapping="Wrap" Text="{Binding}"
VerticalAlignment="Top" Width="447" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,242,0,0"
Name="textBlock5"
Text="Results:" VerticalAlignment="Top" />
<ListBox Height="169" HorizontalAlignment="Left" Margin="6,271,0,0" Name="listBox1"
VerticalAlignment="Top" Width="444" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{StaticResource PhoneForegroundBrush}" Width="418"
BorderThickness="2" Margin="2">
<StackPanel>
<TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap" />
<TextBlock Text="{Binding Path=Url}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Height="209" HorizontalAlignment="Left" Margin="6,446,0,0" Name="textBox1" Text="" VerticalAlignment="Top" Width="444" IsEnabled="True" IsReadOnly="True" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>
The code is currently designed so you can choose to display either one of the example XML files, but nothing is displayed in the Listbox at all.
Any advice would be appreciated. Thank you.
See if the following helps:
string fakeXML = "<subsonic-response status='ok' version='1.1.1'>" +
"<license valid='true' email='foo#bar.com' " +
" key='ABC123DEF' date='2009-09-03T14:46:43'/>" +
"</subsonic-response>";
XDocument doc = XDocument.Parse(fakeXML);
var searchResults = from xe in doc.Elements("subsonic-response")
select new SearchResult
{
Title = xe.Attribute("version").Value,
Url = xe.Attribute("status").Value
};
listBox1.DataContext = searchResults;
textBox1.DataContext = searchResults;

Cannot see the content and image on the user control

I created the user control, I added them in the stackpanel by coding. when it is complier, there is no error. However, I didn't seen any content and image on this user control. When the button is clicked, it open another page. I know the click event is working fine. Would someone show me how to solve the problem? Thanks in advance.
The following is my UserControl.xaml:
<UserControl x:Name="NoButtonListItemControl"
x:Class="PhoneApp1.NobuttonListItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" >
<StackPanel Margin="14,17,20,48" >
<Image Source="{Binding Path=PicFileName,
ElementName=NoButtonListItemControl}"
Width="120" Height="120"></Image>
<Button Content="{Binding Path=Description,
ElementName=NoButtonListItemControl }"
ClickMode="Press"
Click="btnNoButtonListItem_Click" FontFamily="Georgia"
FontSize="15" Foreground="SkyBlue" Height="90"
Width="400" />
<TextBlock Text="{Binding Path=ID,
ElementName=NoButtonListItemControl }"
Style="{StaticResource pageTitleStyle}"
TextAlignment="{Binding}" />
</StackPanel>
</Grid>
 
The following is my UserControl.xaml.cs:
namespace PhoneApp1
{
public partial class NobuttonListItem : UserControl
{
public NobuttonListItem()
{
InitializeComponent();
}
public static DependencyProperty PicFileNameProperty =
DependencyProperty.Register("PicFileName", typeof(string),
typeof(NobuttonListItem), null);
public static DependencyProperty DescriptionProperty =
DependencyProperty.Register("Description", typeof(string),
typeof(NobuttonListItem), null);
public static DependencyProperty IDProperty =
DependencyProperty.Register("ID", typeof(string),
typeof(NobuttonListItem), null);
public string PicFileName
{
get
{
return (string)GetValue(PicFileNameProperty);
}
set
{
SetValue(PicFileNameProperty, value);
}
}
public string Description
{
get
{
return (string)GetValue(DescriptionProperty);
}
set
{
SetValue(DescriptionProperty, value);
}
}
public string ID
{
get
{
return (string)GetValue(IDProperty);
}
set
{
SetValue(IDProperty, value);
}
}
private void btnNoButtonListItem_Click(object sender,
RoutedEventArgs e)
{
App.Navigate(new
Uri(String.Format("/CallPage.xaml?ID={0}",ID),
UriKind.Relative));
}
}
}
 
There is test.xaml page in which I added the user control:
<phone:PhoneApplicationPage xmlns:my="clr-
namespace:PhoneApp1"
x:Class="PhoneApp1.test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-
namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-
namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0"
Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-
7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<StackPanel x:Name="spListPanel" Loaded="spListPanel_Loaded"
Grid.Row="1" Margin="12,0,12,0">
</StackPanel>
<Grid Grid.Row="2" Margin="12,0,12,0">
<StackPanel>
</StackPanel>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
The code behind of the test.xam l page:
namespace PhoneApp1
{
public partial class test : PhoneApplicationPage
{
public test()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
ShowList();
}
void ShowList()
{
int userControlUniqueID = 0;
AddItem("1", "Test 1", "onHold_icon.png", 1);
AddItem("2", "Test 2", "responded_icon.png",2);
}
void AddItem(string id, string description, string fileName,
int userControlUniqueID)
{
NobuttonListItem item = new NobuttonListItem();
item.Name = "lst_" + Convert.ToString(userControlUniqueID);
item.ID = id;
item.Description = description;
item.PicFileName = "/images" + "/" +fileName;
spListPanel.Children.Add(item);
}
}
}
Don't forget to add the following code in your "CodeBehind" file
this.DataContext = this;
If it still doesn't work, please post some of the output in the output window

Disable pivot flick for WP7

seeing this blog post : http://mine.tuxfamily.org/?p=111, I'm trying to disable the pivot flick when flicking on a control inside the pivot.
I've tryed the proposed solution with IsHitTestVisible, but it seems that the application locks when setting it to false.
To reproduce the problem, create a wp7 basic application. Use this xaml :
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<controls:Pivot Name="pivotCtrl" Grid.Row="1">
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value1}"/>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Height="38" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Text="{Binding Value1}" />
<TextBlock Grid.Row="1" Height="38" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Text="{Binding Value2}" />
<Canvas Grid.Row="2" Width="400" Height="300" Background="Yellow" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" />
</Grid>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
</Grid>
</Grid>
with this code behing :
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
List<Element> elements = new List<Element>();
for (int i = 0 ; i < 10 ; i++)
elements.Add(new Element { Value1 = "Value - " + i, Value2 = "Something - " + i});
pivotCtrl.ItemsSource = elements;
}
private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("On");
pivotCtrl.IsHitTestVisible = true;
}
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("Off");
pivotCtrl.IsHitTestVisible = false;
}
}
public class Element
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
In debug mode, I can see the "Off" value, but never the "On" one.
Maybe there's another solution for this.
Thanks in advance for your help.
This solution was posted this week. Does it work better for you?
Preventing the Pivot or Panorama controls from scrolling

Resources