1

Windowsストアアプリで作業していて、一部のデータが更新されたときにlistViewを更新/更新しようとしています. しかし、私が読んだすべてのサンプルとドキュメントにもかかわらず、機能しません...

ここに私のコードビハインド: (私は xaml ファイルを提供しません。これは単なるサンプルの listView です)。

したがって、INotifyPropertyChanged インターフェイスを実装するクラス:

public class Download : INotifyPropertyChanged
    {
        public enum DownloadState
        {
            Running,
            Waiting,
            Pausing,
            Paused,
            Cancelling,
            Cancelled
        };

        private String Uri;
        private StorageFile storageFile;
        private String tempFileName;



        private String fileName;
        private String version ;

        private long totalSize ;
        private long downloadedBytes;

        private DownloadState state;
        private Protocol protocol;


        public Download(String Uri, StorageFile file, String fileName, String version, long totalSize, Protocol protocol)
        {
            this.Uri = Uri;
            this.storageFile = file;
            this.tempFileName = "";
            this.fileName = fileName;
            this.version = version;

            this.totalSize = totalSize;
            this.downloadedBytes = 0;

            this.state = DownloadState.Waiting;

            this.protocol = protocol;


        }


        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            System.Diagnostics.Debug.WriteLine("Update!"); //ok
            if (PropertyChanged != null)
            {
                //PropertyChanged is always null and shouldn't.
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
           public DownloadState State
        {
            get{return this.state;}
            set { 
                this.state = value;
                NotifyPropertyChanged();
            }
        }

        //+some others methods

    }
}

そしてメトロアプリのメインページ:

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace ClientAirNavLight_WS
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class MainPage : ClientAirNavLight_WS.Common.LayoutAwarePage
    {
        /// <summary>
        /// Represent a Web Service proxy.
        /// </summary>
        private AirNavLight_WSClientClient proxyWS;

        /// <summary>
        /// Initiialize the component of the application's main page.
        /// </summary>
        public MainPage()
        {
            this.InitializeComponent();          

        }



        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }


        //Simulate data update.
        private async void Button_Click(object sender, RoutedEventArgs e)
        {

            object selected = this.ListResult.SelectedItem;
            if (selected != null)
            {
                //simulate an update in data.
                // ListView should be refresh in order to reflect changes made here.
                Download dl = (Download)selected;
                if (dl.State == Download.DownloadState.Paused)
                {
                    dl.State = Download.DownloadState.Running;
                }
                else
                {
                    dl.State = Download.DownloadState.Paused;
                }

            }
            else
            {
                //Just add an item to the list view.
                StorageFile file = await this.getStorageFile("test");
                Download dl = new Download("192.128.2.14", file, "test", "1.2", 100, Protocol.HTTP);
                this.ListResult.Items.Add(dl);


                this.ListResult.DataContext = dl;// Does not work.


            }
        }


        private async Task<StorageFile> getStorageFile(String suggestedFileName)
        {
            FileSavePicker savePicker = new FileSavePicker();
            savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            // Dropdown of file types the user can save the file as
            savePicker.FileTypeChoices.Add("Application/pdf", new List<string>() { ".pdf" });
            savePicker.FileTypeChoices.Add("Archive", new List<string>() { ".zip", ".rar", ".7z" });
            savePicker.FileTypeChoices.Add("Plain-text", new List<string>() { ".txt" });
            // Default file name if the user does not type one in or select a file to replace
            savePicker.SuggestedFileName = suggestedFileName;
            return await savePicker.PickSaveFileAsync();
        }


    }
}

では、listView.DataContext をどのように使用すればよいのでしょうか? INotifyPropertyChanged の使い方を誤解していますか?

編集 :

私のlistViewがどのように定義されているか:

 <ListView x:Name="ListResult" HorizontalAlignment="Left" Height="200" Margin="10,56,0,0" VerticalAlignment="Top" Width="653" SelectionMode="Single"/>
4

3 に答える 3

3

なぜあなたは設定していますthis.ListResult.DataContext = dlか?ListViews を扱う場合、ItemsSource は反復されるすべてのオブジェクトのコレクションであり、DataContext ではありません。さらに、ItemsSource は 1 つのアイテムではなくコレクションである必要があります。したがって、プロパティにバインドしている場合、そのプロパティは ItemsSource コレクション内の項目のプロパティとして存在する必要があります。

ただし、コレクションがないように見えるため、dl を ListView に直接追加していますthis.ListResult.Items.Add(dl)this.ListResult.DataContext = dlそのアプローチは機能するはずですが、コレクションにor セットを取り出し、this.ListResult.ItemsSourceそのコレクションに dl を追加します

よくわかりません[CallerMemberName]が、propertyName が null であることに問題がある場合は、次のことを試してください。

    public DownloadState State
    {
        get{return this.state;}
        set {
            if( this.state != value )
            {
                this.state = value;
                NotifyPropertyChanged("State");
            }
        }
    }

さらに、次のように、バインドするすべてのプロパティをパブリックにして、NotifyPropertyChanged を呼び出す必要があります。

    private long totalSize ;

    public long TotalSize
    {
        get{return this.totalSize;}
        set {
            if( this.totalSize != value )
            {
                this.totalSize = value;
                NotifyPropertyChanged("TotalSize");
            }
        }
    }
于 2013-08-13T18:03:45.703 に答える
-1

Zangdak -- この問題を回避する 1 つの方法は、コレクション内の項目が変更されるたびに、ListView の ItemSource を null に設定してからコレクションに戻すことです。これを行うと、UI が更新され、コレクションに追加された新しいアイテムが表示されます。

ペイジ・エイク

于 2015-03-26T21:17:11.560 に答える