none
WPF 跨執行緒 學習 RRS feed

  • 問題

  • Windows Form , 執行緒會傳回名稱、數值並觸發AddItem() ,  , 如果是新的名稱就建立item , 不是就只修改item數值

            ConcurrentDictionary<string, ListViewItem> DicVals = new ConcurrentDictionary<string, ListViewItem>();
    
            delegate void AddItem2ListView(List<TValue> vals);
            void AddItem(List<TValue> vals)
            {
                if (this.InvokeRequired)
                    this.Invoke(new AddItem2ListView(AddItem), vals);
                else
                {
                    foreach (TValue val in vals)
                    {
                        if (DicVals.ContainsKey(val.Name))
                            DIcVals[val.Name].SubItems[1].Text = val.Value.ToString();
                        else
                        {
                            ListViewItem lvi = new ListViewItem(new string[] { val.Name, val.Value.ToString() });
                            DicVals[val.Name] = lvi;
                            listView1.Items.Add(lvi);
                        }
                    }
                }
            }

    嘗試的WPF

    XML:

    <ListView Name="listview1" HorizontalAlignment="Left" Height="340" Margin="10,19,0,0" VerticalAlignment="Top" Width="430">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Name" Width="200" DisplayMemberBinding="{Binding Name}"/>
                        <GridViewColumn Header="Value" Width="200" DisplayMemberBinding="{Binding Value}"/>
                    </GridView>
                </ListView.View>
            </ListView>

    CS:

    SendOrPostCallback addItemHandle = delegate (object obj)
                    {
                            foreach (TValue val in vals)
                            {
                                if (DicVals.ContainsKey(val.Name))
                                    DicVals[val.Name].Value = val.Value.ToString();
                                else
                                {
                                    ValueItem tvi = new ValueItem() { Name = val.Name, Value = val.Value.ToString() };
                                    DicVals[val.Name] = tvi;
                                    listview1.Items.Add(tvi);
                                }
                            }
                    };
     _syncContext.Post(addItemHandle, null);

    目前這版問題是ConcurrentDictionary紀錄的並不是listview的item而是自行建立的ValueItem類別 , 所以無法直接修改指定item的數值

    Q1.上述功能目前是只有class與xmal 並沒有viewmodle是否是好的架構呢?如果不是甚麼才是較好的架構呢?

    Q2.WPF該如何達到功能?










    • 已編輯 StuBoo 2018年9月12日 上午 03:49
    2018年9月12日 上午 03:36

解答

  • 牽涉的觀念很多,建議你從這邊看起 https://docs.microsoft.com/zh-tw/dotnet/framework/wpf/data/data-binding-wpf

    Q4: 基本上跨執行緒和 Dictionary 或 ObservableCollection 無關。

    註: 我們之所以喜歡用 ObservableCollection 是因為它具有屬性變更通知以及集合變更通知的功能。


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/


    2018年9月13日 上午 04:23
    版主

所有回覆

  • 以 WPF 的慣例來說,我們習慣產生資料 (View Model),然後直接指派 IEnumerable 型別物件 (一般習慣用 ObservableCollection<T>) 給 ListView 的 ItemsSource 屬性。 而不是用 Items.Add method

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/


    2018年9月12日 下午 03:15
    版主
  • 以 WPF 的慣例來說,我們習慣產生資料 (View Model),然後直接指派 IEnumerable 型別物件 (一般習慣用 ObservableCollection<T>) 給 ListView 的 ItemsSource 屬性。 而不是用 Items.Add method

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/


    xml

    ItemsSource="{Binding OCTest}"   無效

    cs

    public ObservableCollection<Values> OCTest = new ObservableCollection<Values>();

    public MainWindow()
    {
                InitializeComponent();
                listview1.ItemsSource = OCTags;
    } private void Button_Click(object sender, RoutedEventArgs e) { OCTest.Add(new Values{ Name = "123", Value = "123" }); } public class Values { public string Name { get; set; } public string Value { get; set; } }

    Q1.想請問有沒有範例? ListView ItemSource 跨執行緒 新增、修改Item , 找網路自行試驗發現更多疑惑...

    Q2.我用xml的方式繫結總是沒有用 而如果以程式碼的方式才會有效果 , 哪裡錯誤了嗎?

    Q3.ObservableCollection是集合沒辦法像Dictionary的形式 ,  如果要修改集合內的某個項目 , 是不是只能取出每一個項目後進行比對?沒辦法如Dictionary?

    Q4.ObservableCollection沒辦法跨執行緒 , 想請問有沒有其他的方式?






    • 已編輯 StuBoo 2018年9月13日 上午 03:39
    2018年9月13日 上午 02:07
  • 牽涉的觀念很多,建議你從這邊看起 https://docs.microsoft.com/zh-tw/dotnet/framework/wpf/data/data-binding-wpf

    Q4: 基本上跨執行緒和 Dictionary 或 ObservableCollection 無關。

    註: 我們之所以喜歡用 ObservableCollection 是因為它具有屬性變更通知以及集合變更通知的功能。


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/


    2018年9月13日 上午 04:23
    版主