如何在合成后将InputBindings添加到Window?

时间:2013-01-02 09:31:36

标签: wpf mef inputbinding

我正在尝试通过实现我自己的着名计算器示例版本来掌握MEF框架。用户界面在WPF中。

在合成之后,Viewmodel会保存ObservableCollection(Of IOperation),该视图由Buttons中的“ListBox”表示。每个Button上的文字都是CharIOperation定义的Symbol属性。通过将ListBox的SelectedItem绑定到ViewModel中的属性,我可以在不知道按下了哪个Calculate的情况下触发当前所选IOperation的{​​{1}}方法。 (代码说明如下。)

但是,现在我需要将Button添加到视图中,其中每个InputBindings将与KeyBinding上定义的Symbol相关联。看起来我无法避免实现IOperationSelect Case)语句来迭代Viewmodel的switch集合来选择应该调用'Calculate`方法的那个。

有什么想法吗?

THE XAML:

IOperation

的IOperation:

<ListBox Grid.Column="1" Grid.Row="3" Name="OperationsList" 
         SelectedItem="{Binding ActiveOperation,Mode=TwoWay}"
         ItemsSource="{Binding Operations}">
         <ListBox.ItemsPanel>
             <ItemsPanelTemplate>
                 <UniformGrid IsItemsHost="True"/>
             </ItemsPanelTemplate>
         </ListBox.ItemsPanel>
         <ListBox.ItemTemplate>
             <DataTemplate>
                 <Button Content="{Binding Symbol}"
                         ToolTip="{Binding Description}"
                         Command="{Binding ElementName=OperationsList, Path=DataContext.ActivateOperation}"
                            Click="Button_Click_1"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

视图模型:

Public Interface IOperation
    Function Calculate() As Double
    Property Left As Double
    Property Right As Double
    Property Symbol As String
    Property Description As String
End Interface

1 个答案:

答案 0 :(得分:1)

代码是关于边缘的粗略所以相应调整......

// in ViewModel, after composition

// map string symbols to input Keys (for brevity, using a Dictionary)
Dictionary<string, System.Windows.Input.Key> SymbolsToKeys = new Dictionary<string, Key>
{
  { "+", Key.Add },
  // etc.
}

// compose the list (expose it via a public property)
// (ensure not to get confused: the KeyValuePair.Key is for the string symbol
// ... and the KeyValuePair.Value is for the Sys.Win.Input.Key value)
KeyBindings = (from symbolAndKey in SymbolsToKeys
               join op in Operations on Equals(symbolAndKey.Key, op.Symbol)
               select new KeyBinding(
                 new Command(op.Calculate)),
                 new KeyGesture(symbolAndKey.Value)
              ).ToList();

// in View, after Binding to ViewModel
var vm = DataContext as YourViewModel;
if(vm != null)
{
   foreach(var keybinding in vm.KeyBindings){
       this.InputBindings.Add(keybinding);
   }
}