1

ローカル SQLite データベースを使用して Windows Phone 7 アプリケーションに取り組んでおり、DataBinding を使用するページのレンダリング時間に問題があります。

現在、データベースからデータを取得するには 60 ~ 70 ミリ秒かかります。次に、ListBox と DataBinding を使用して取得したデータをレンダリングするのに約 3100 ミリ秒かかります。

ここでは、ListBox の DataTemplate を確認できます。

<DataTemplate x:Key="ListBoxItemTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="68" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <TextBlock x:Name="TimeColumn"
                        Text="{Binding TimeSpan}" Grid.Column="0" Grid.Row="0"
                        Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
        <TextBlock Text="{Binding Stop.StopName}" Grid.Column="1" Grid.Row="0" 
                                Margin="15,0,0,0" TextWrapping="NoWrap" Foreground="Black"
                                HorizontalAlignment="Left" VerticalAlignment="Center" />
    </Grid>
 </DataTemplate>

コメント: Grid の代わりに Canvas を使用して試してみましたが、同じ結果です。

次に、データベースは (ViciCoolStorage を使用して) CSList にデータをロードし、ListBox にバインドされます。

StationList.ItemsSource = App.RouteViewModel.RouteStops;

コメント: CSList の要素を ObservableCollection に追加し、それをインターフェイスにバインドしようとしましたが、何も変更されていないようです。

質問: たとえ 10 個の要素をロードしたとしても、膨大なロード時間の原因となる何か間違ったことをしていますか、それともこれは正常なことですか? DataBinding でパフォーマンスを向上させるための推奨事項はありますか?

事前にご回答いただきありがとうございます。

対応するコード部分:

RouteViewModel.cs

private Route rRoute;
public Route Route
{
    get
    {
        if (rRoute != null)
        {
            return rRoute;
        }
        else
        {
            return new Route();
        }
    }
}

public void LoadRoute(string index)
{
    try
    {
        if (rRoute.RouteId != index)
        {
            RouteLoaded = false;
            StationsLoaded = false;
            TimetableLoaded = false;
        }
    }
    catch (Exception) { }

    this.index = index;

    if (!RouteLoaded)
    {
        NotifyPropertyChanging("Route");
        rRoute = Route.ReadSafe(index);
        RouteLoaded = true;
        NotifyPropertyChanged("Route");
    }
}

private CSList<RouteTime> rtLine;
public CSList<RouteTime> RouteStops
{
    get
    {
        if (rtLine != null)
        {
            return rtLine;
        }
        else
        {
            return new CSList<RouteTime>();
        }
    }
}

public void LoadRouteStops()
{
    LoadRoute(index);

    if (!this.StationsLoaded)
    {
        NotifyPropertyChanging("RouteStops");
        rtLine = rRoute.RouteTimes.FilteredBy("DirectionId = @DirectionId", "@DirectionId", this.direction).OrderedBy("TimeSpan");
        NotifyPropertyChanged("RouteStops");

        StationsLoaded = true;
    }
}

RouteView.xaml.cs

private string index;
private bool visszaut = false;

public RouteView()
{
    InitializeComponent();
    Loaded += new System.Windows.RoutedEventHandler(RouteView_Loaded);
}

void RouteView_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    DataContext = App.RouteViewModel;
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    NavigationContext.QueryString.TryGetValue("index", out index);

    App.RouteViewModel.LoadRoute(index);
    App.RouteViewModel.Direction = Convert.ToInt32(visszaut);
    App.RouteViewModel.LoadRouteStops();
    StationList.ItemsSource = App.RouteViewModel.RouteStops;
}

RouteTime.cs -クラスの実装

[MapTo("RouteTimes")]
public class RouteTime : CSObject<RouteTime, int>
{
    public int RouteTimeId
    {
        get
        {
            return (int)GetField("RouteTimeId");
        }
        set
        {
            SetField("RouteTimeId", value);
        }
    }

    public int RouteId
    {
        get
        {
            return (int)GetField("RouteId");
        }
        set
        {
            SetField("RouteId", value);
        }
    }

    public int StopId
    {
        get
        {
            return (int)GetField("StopId");
        }
        set
        {
            SetField("StopId", value);
        }
    }

    public int TimeSpan
    {
        get
        {
            return (int)GetField("TimeSpan");
        }
        set
        {
            SetField("TimeSpan", value);
        }
    }

    public Direction DirectionId
    {
        get
        {
            return (Direction)GetField("DirectionId");
        }
        set
        {
            SetField("DirectionId", value);
        }
    }

    [OneToOne(LocalKey = "StopId", ForeignKey = "StopId")]
    public Stop Stop
    {
        get
        {
            return (Stop)GetField("Stop");
        }
        set
        {
            SetField("Stop", value);
        }
    }

    [ManyToOne(LocalKey = "RouteId", ForeignKey = "RouteId")]
    public Route Route
    {
        get
        {
            return (Route)GetField("Route");
        }
        set
        {
            SetField("Route", value);
        }
    }
}
4

5 に答える 5

1

さて、このシナリオでは、遅いレンダリングの原因は RouteTime クラスと Stop クラスの間の [OneToOne] 接続だったようです。リンクされたクラスに格納されている変数のいずれかにバインドすると、レンダリングに時間がかかります。

によって修正されました

結果を表示する必要があるコードに新しい部分クラスを追加しました。

public partial class StopTimes
{
    public int TimeSpan
    {
        get;
        set;
    }

    public string StopName
    {
        get;
        set;
    }
}

Vici CoolStorage でアドホック クエリを使用して、必要なデータと viola を要求する独自のクエリを作成しました。すべてがそこにあり、レンダリングに 1 秒もかかりませんでした。おそらく、レンダリング中に SQLQuery を使用して StopName フィールドを 1 つずつ要求するのでしょうか。

わかりませんが、とにかく助けてくれてありがとう:)

于 2012-11-13T14:37:50.497 に答える
0

問題は、多くのバインディングを設定することが主な原因です。バインディングを最小限に保ち、コード ビハインドで大変な作業を行うようにしてください。そのような;

「文字列のリストをxaml に 1 つずつバインドする」と「テキスト ブロックに 1 つだけバインドする
string.join
メソッドを使用する」

私が持っていた

<TextBlock Text="{Binding Times[0]}"/>
<TextBlock Text="{Binding Times[1]}"/>
...
<TextBlock Text="{Binding Times[9]}"/>

そしてに変更

<TextBlock Text="{Binding TimesToLongString}"/>

これにより、遅延が修正されました。
3つのアイテムを9秒でロードするために使用。
現在、10 アイテムで 110 ミリ秒以内にロードされます。

リストの読み込みにかかる時間を確認するには、この投稿をチェックしてください。

于 2015-01-13T21:03:50.943 に答える
0

私は混乱しています: Windows Phone 7 でローカル SQLite をどのように実行しますか? これがサポートされているWP8を意味しましたか? いずれにせよ、LongListSelector (WP8 に組み込まれている - WP7 のツールキット) の使用を検討してください。これは、レンダリングするアイテムが多数ある場合に仮想化でより適切に機能するためです。

于 2012-11-13T00:56:41.660 に答える
0

このシナリオでは、DataBinding が問題になることはありません。問題はありませんでした。確かにSQL DBと関係があります。約 200 個のアイテムのリストがあり、100 ミリ秒という妥当なタイムスロットで問題なく表示されました。

それはあなたのSQL実装であるか、ViciCoolStorageを間違って使用しています. コードを投稿してください。

于 2012-11-10T04:57:26.123 に答える
0

LoadRouteStops() メソッドの外でリストのフィルタリングを試みましたか? たぶん、viewModel の代わりにコード ビハインドでしょうか? propertyChanging 通知と propertyChanged 通知の間で、多くの作業を行う必要があるようです。

于 2012-11-12T23:06:54.513 に答える