LongListSelector on WP8 linq-to-sql binding issue

2020-08-01 06:17发布

问题:

I'm building my first WP8 app that connects via linq-to-sql to Database and I wanted to show there data in LongListSelector. But nothing appears just black screen after starting up in Emulator.

May I ask where do I make mistake? I use WCF to connect

this is MainPage.xaml.cs

    using PhoneApp1.Resources;
using PhoneApp1.ToursServiceReference1;


    namespace PhoneApp1

{
    public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Sample code to localize the ApplicationBar
        //BuildLocalizedApplicationBar();
    }
    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        ToursServiceReference1.ToursService1Client serviceClient = new ToursServiceReference1.ToursService1Client();

        serviceClient.GetAllKlientsCompleted += new EventHandler<ToursServiceReference1.GetAllKlientsCompletedEventArgs>(serviceClient_GetAllKlientsCompleted);

        serviceClient.GetAllKlientsAsync();
    }
    private void serviceClient_GetAllKlientsCompleted(object sender, ToursServiceReference1.GetAllKlientsCompletedEventArgs e)
    {
        if (e.Result != null)
        {
            LLS.ItemsSource = e.Result;
        }

    }

t

this is MainPage.xaml

<phone:PhoneApplicationPage
x:Class="PhoneApp1.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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="ToursDataTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Margin="10" Text="{Binding name}"/>

        </StackPanel>
    </DataTemplate>
    <Style x:Key="LongListSelectorStyle1" TargetType="phone:LongListSelector">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="phone:LongListSelector">
                    <Grid Background="{TemplateBinding Background}" d:DesignWidth="480" d:DesignHeight="800">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ScrollStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="00:00:00.5"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Scrolling"/>
                                <VisualState x:Name="NotScrolling"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


</phone:PhoneApplicationPage.Resources>

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="0*"/>
    </Grid.RowDefinitions>

    <!-- LOCALIZATION NOTE:
        To localize the displayed strings copy their values to appropriately named
        keys in the app's neutral language resource file (AppResources.resx) then
        replace the hard-coded text value between the attributes' quotation marks
        with the binding clause whose path points to that string name.

        For example:

            Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"

        This binding points to the template's string resource named "ApplicationTitle".

        Adding supported languages in the Project Properties tab will create a
        new resx file per language that can carry the translated values of your
        UI strings. The binding in these examples will cause the value of the
        attributes to be drawn from the .resx file that matches the
        CurrentUICulture of the app at run time.
     -->

    <!--TitlePanel contains the name of the application and page title-->

    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"/>
    <TextBlock HorizontalAlignment="Left" Margin="60,44,0,-91" Grid.Row="1" TextWrapping="Wrap" Text="Připojení SQL" VerticalAlignment="Top" Height="47" Width="348" TextAlignment="Center" FontWeight="Bold" FontSize="36"/>
    <phone:LongListSelector x:Name="LLS" HorizontalAlignment="Left" ItemsSource="{Binding name}" ItemTemplate="{StaticResource ToursDataTemplate}" Height="407" Margin="47,164,0,-571" Grid.RowSpan="2" VerticalAlignment="Top" Width="365"/>

    <!--Uncomment to see an alignment grid to help ensure your controls are
        aligned on common boundaries.  The image has a top margin of -32px to
        account for the System Tray. Set this to 0 (or remove the margin altogether)
        if the System Tray is hidden.

        Before shipping remove this XAML and the image itself.-->
    <!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
</Grid>

Sorry for providing that large code but as I don't know so far where the mistake might be I published full code.

Thank you everyone for your time.

回答1:

Edit: Woops, I'm sorry, I didn't read that you are using WCF for this, since I thought WebAPI will be ok here (regarding to your question to web api and referencing your question here). But maybe you do not need to stick with WCF and can use other technologies?

Marek, please take a look at https://stackoverflow.com/a/18271995/959687 again, for the basics. I'm writing the following code out of my head, so it may need to be improved afterwards. But it will show you how it is basically done.

I will show you, how to populate your LongListSelector with items from a webservice.

At first we need our data transfer object (DTO):

[JsonObject]
public class ListDTO
{
  [JsonProperty]
  public IEnumerable<string> Items { get; set; }
}

Then you need a controller for this:

public class ListController : ApiController
{
  [HttpGet]
  public ListDTO Get() 
  {
    return new ListDTO() 
    {
      Items = new List<string>() 
      {
        "Item 1",
        "Item 2",
      },
    };
  }
}

Then you will need to retrieve those items from the service within your app:

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
  LoadFromWebservice();
}

private async void LoadFromWebservice()
{
    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri("http://thewebservice.tld/");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    await client.GetStreamAsync("api/list/get")
        .ContinueWith(result =>
    {
        var stream = result.Result;
        var serializer = new JsonSerializer(); // this is json.net serializer
        using (var streamReader = new StreamReader(stream))
        {
            using (var jsonReader = new JsonTextReader(streamReader))
            {
                var theList = serializer.Deserialize<ListDTO>(jsonReader);
                Dispatcher.BeginInvoke(() => LLS.ItemsSource = theList.Items.ToList());
            }
        }
    });
}

You can now retrieve your items within the controller with ling-to-sql from a database or something. Feel free to do, whatever you want. :-)

But be aware: I do not recommend it doing it this way, since it is too much coupled to your user interface. This example shows you the very basic of getting data from a webservice.

I will recommend you to take a look at the MVVM pattern (http://en.wikipedia.org/wiki/Model_View_ViewModel), build a viewmodel and bind your view to that viewmodel. A way of doing this is using MVVM light: http://mvvmlight.codeplex.com/

Additional information

  • If you want to test it on your local machine, please take a look here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj684580%28v=vs.105%29.aspx
  • To use the httpclient, you need to install the package from NuGet
  • To deploy it the solution, so everyone can access it, you need a webspace running .NET 4.5, create a Deployment-Package (http://msdn.microsoft.com/en-us/library/dd465323.aspx) and upload it to your server
  • For accessing your MS SQL Database, you can use ling-to-sql, entity framework, or anything else .NET supports.