2013-11-27 80 views
1

我並不擅長整個MVVM設計模式。儘管我覺得這個項目會受益於它,請記住,這個項目是從Winforms轉換而來的,並且我當時只是在學習WPF。這就是說該項目的想法是一個鍵盤楔和鍵盤鉤。當程序加載時,主窗口變得不可見,並且系統托盤上的圖標允許主窗口再次變爲可見。當主窗口可見時,在其中央有一個列表框,允許分配/定義楔形和熱鍵。僅供參考,我將通過鍵盤鉤子監控的按鍵稱爲熱鍵。因此可以說我正在監控HotKeys F13-F15,並且我有2個鍵盤楔子。項目模板視圖非常簡單。多個ItemSources綁定

<UserControl x:Class="Keymon.UserControls.HotkeyConfigurationView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid Margin="3,0"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="3*" /> 
      <ColumnDefinition Width="2*" /> 
     </Grid.ColumnDefinitions> 
     <TextBlock Text="{Binding Key}" TextWrapping="Wrap" /> 
     <TextBlock Grid.Column="1" Text="{Binding Path}" HorizontalAlignment="Right" TextWrapping="Wrap" /> 
    </Grid> 
</UserControl> 

或簡單地將2個文本塊並排綁定到Key和Path。

我做我的熱鍵和KeyboardWedges實現這個

public interface IMyAdvancedListItem 
{ 
    string Key { get; } 
    string Path { get; } 
    string Parameters { get; } 
} 

當我的程序第一次啓動時我檢查,看看我有什麼計算機上,給了我熱鍵和鍵盤楔子的適當列表。我添加這些正確的名單,然後同時收集值的列表,並摔在IMyAdvancedListItem ......我結束了移動到模型視圖爲MyAdvancedList

public class MyAdvancedListViewModel 
{ 
    public List<Keymon.ValueTypes.IMyAdvancedListItem> Keys 
    { 
     get 
     { 
      System.Collections.Generic.List<Keymon.ValueTypes.IMyAdvancedListItem> list = new System.Collections.Generic.List<ValueTypes.IMyAdvancedListItem>(); 
      list.AddRange(Globals.MonitoredKeys.Values.Cast<Keymon.ValueTypes.IMyAdvancedListItem>()); 
      list.AddRange(Globals.SerialPortWedges.Values.Cast<Keymon.ValueTypes.IMyAdvancedListItem>()); 
      return list; 
     } 
     set 
     { 
     } 
    } 

    public MyAdvancedListViewModel() 
    { 
    } 

} 

最後當上一個列表框項目的用戶雙擊我有它打開正確的配置對話框,然後更新正確的列表。它更新列表我告訴它刷新後的項目(似乎沒有做任何事情)

private void ListBox_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     var keyListBox = sender as ListBox; 
     var temp = keyListBox.SelectedItem as Keymon.ValueTypes.IMyAdvancedListItem; 
     var index = keyListBox.SelectedIndex; 

     if (Globals.SerialPortWedges.ContainsKey(temp.Key)) 
     { 
      if (temp.Key == "MSR") 
       ConfigurationHelper.ConfigureWedge(temp.Key); 
      else 
       ConfigurationHelper.ConfigureWedgeEx(temp.Key); 
     } 
     else 
     { 
      ConfigurationHelper.ConfigureHotKey(temp as HotkeyConfiguration); 
     } 
     keyListBox.Items.Refresh(); 
     keyListBox.SelectedIndex = index; 
    } 

現在,你可能會想幹脆實行INotifyCollection ..做過一樣。我甚至嘗試過INotifyProperty。我認爲最終這一切都可以歸結爲我只是猜測我應該做什麼,而不理解我真的在做什麼。這裏僅供參考是來自兩個列表的幾行重要代碼。

public class GlobalHotKeys : INotifyCollectionChanged, INotifyPropertyChanged, IEnumerable 
{ 
    public GlobalHotKeys() 
    { 
    } 
    public HotkeyConfiguration this[int key] 
    { 
     get 
     { 
      return MonitoredKeys[key]; 
     } 
     set 
     { 
      MonitoredKeys[key] = value; 
      NotifyCollectionChanged(NotifyCollectionChangedAction.Replace, value); 
      NotifyPropertyChanged("Keys"); 
     } 
    } 

    private Dictionary<int, HotkeyConfiguration> MonitoredKeys = new Dictionary<int, HotkeyConfiguration>(); 
    public IEnumerable<HotkeyConfiguration> Values { get { return MonitoredKeys.Values; } } 

    #region Notifications 
    private void NotifyCollectionChanged(NotifyCollectionChangedAction action, object affectedObject) 
    { 
     if (CollectionChanged != null) 
     { 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, affectedObject)); 
     } 
    } 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 
    private void NotifyPropertyChanged(string property) 
    { 
     if(PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

} 

,這裏是我的挖起杆

public class GlobalWedges : IEnumerable, INotifyCollectionChanged 
{ 
    public GlobalWedges() 
    { 
     wedges = new Dictionary<string, KeyboardWedgeConfiguration>(); 
    } 
    public KeyboardWedgeConfiguration this[string key] 
    { 
     get 
     { 
      if (wedges.ContainsKey(key)) 
       return wedges[key]; 
      else 
       return null; 
     } 
     set 
     { 
      wedges[key] = value; 
      NotifyCollectionChanged(NotifyCollectionChangedAction.Replace, value); 
     } 
    } 

    private Dictionary<string, KeyboardWedgeConfiguration> wedges; 
    public IEnumerable<KeyboardWedgeConfiguration> Values { get { return wedges.Values; } } 

    #region Notifications 
    private void NotifyCollectionChanged(NotifyCollectionChangedAction action, object affectedObject) 
    { 
     if (CollectionChanged != null) 
     { 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, affectedObject)); 
     } 
    } 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 
    #endregion 

} 

我不應該覺得你需要在上述清單所以這裏只是類勾勒出項目的代碼。

public class KeyboardWedgeConfiguration : Keymon.ValueTypes.IMyAdvancedListItem, Keymon.ValueTypes.Saveable, IDisposable 
public class HotkeyConfiguration : Keymon.ValueTypes.IMyAdvancedListItem 

對不起,關於所有的代碼,但更好有太多不夠。哦,我可能忘了。我必須先關閉程序,然後才能看到對熱鍵列表或鍵盤楔形所做的更改。我知道他們正在更新,因爲如果我更新一個密鑰來說打開一個計算器,那麼它會這樣做。任何幫助,爲什麼?

編輯

只有列表中的這張照片。在此屏幕截圖之後,我編輯了F13以打開calc.exe,但列表仍然是這樣的。 MyAdvancedList

因此,要顯示實際更新,我必須退出我的應用程序,然後重新啓動它。這是我希望程序在刷新時做的。 MyAdvancedListAfter

+0

'System.Collections.Generic.List list = new System.Collections.Generic.List ();' - 人類歷史上最好的C#代碼行。 –

+0

你碰巧有一個gui的樣子嗎? – Kcvin

+0

@NETscape請參閱編輯。 –

回答

1

這個問題不是因爲我幫助過你(或者不是因爲我幫助過你),因爲這個列表並沒有在GUI上刷新,事實上你正在創建一個與ItemsSource綁定的副本用戶界面,更改該副本,並無所作爲。

在這裏你讓你的副本:

var temp = keyListBox.SelectedItem as Keymon.ValueTypes.IMyAdvancedListItem; 
var index = keyListBox.SelectedIndex; 

然後在ConfigurationHelper.Configure____(temp.Key)在這裏你會改變或更新列表中的這個副本。此時,您期待您對列表所做的更改在綁定的ItemsSource中生效;但是,因爲它是一個副本,除非更新綁定列表,否則實際上什麼都不會發生!

你需要做的事情就像你的ConfigurationHelper.Configure_____(temp.Key)返回改變的項目,然後採取該項目並更新綁定的ViewModel的集合並通知GUI該集合已經改變。

注意:這個問題的問題在私人電子郵件中完全解決,但是這是我提供的信息,它讓羅伯特從右腳開始。