我在理解命令参数绑定如何工作方面遇到了一些麻烦.
当我在调用InitializeComponent之前创建一个widget类的实例时,它似乎工作正常.对ExecuteCommand函数中的参数(Widget)的修改将"应用"到_widget.这是我预期的行为.
如果在InitializeComponent之后创建了_widget的实例,我会在ExecuteCommand函数中获得e.Parameter的空引用异常.
为什么是这样?如何使用MVP模式进行此工作,在创建视图后可以创建绑定对象?
public partial class WidgetView : Window
{
    RoutedCommand _doSomethingCommand = new RoutedCommand();
    Widget _widget;
    public WidgetView()
    {
        _widget = new Widget();
        InitializeComponent();
        this.CommandBindings.Add(new CommandBinding(DoSomethingCommand, ExecuteCommand, CanExecuteCommand));
    }
    public Widget TestWidget
    {
        get { return _widget; }
        set { _widget = value; }
    }
    public RoutedCommand DoSomethingCommand
    {
        get { return _doSomethingCommand; }
    }
    private static void CanExecuteCommand(object sender, CanExecuteRoutedEventArgs e)
    {
        if (e.Parameter == null)
            e.CanExecute = true;
        else
        {
            e.CanExecute = ((Widget)e.Parameter).Count < 2;
        } …在我的窗口中,我有加载和保存方法的按钮.我使用CommandBinding,并且save-button具有CanExecute属性,以防止用户在加载数据之前保存数据.
CanExecute-Methode连接到一个名为"canSaveXML"的简单bool值
private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (canSaveXML == false)
    {
        e.CanExecute = false;
    }
    else
    {
        e.CanExecute = true;
    }
    e.Handled = true;
} 
我的意图是在加载数据后设置canSaveXML = true,但是在值发生更改后控件不会刷新.我做了一些阅读,发现我必须调用CommandManager.InvalidateRequerySuggested.我现在这样做,我的代码看起来像这样.
canSaveXML = true;
CommandManager.InvalidateRequerySuggested();
但控件(按钮)仍然不刷新.我仍然被禁用,直到我在UI上触发任何内容或最小化/最大化窗口.我这样做后按钮启用.
这有什么不对?
在MSDN示例中,一次又一次地使用dispatchertimer调用CommandManager.InvalidateRequerySuggested,但我拒绝相信这将是唯一的解决方案.
我正在尝试学习MVVM模式.我遇到的主要问题是学习我应该在哪里声明,创建和绑定命令对象.
2个例子:
我有一个主要形式,就像一个开关板或主菜单.显示选择按钮1和视图1,选择按钮2,显示视图2.大.现在我想回到主窗体,所以我需要一个名为"主菜单"的视图1(和视图2)上的按钮.我应该在哪里定义命令和命令处理程序,以便我可以绑定到"ShowMainMenu"命令?我可以在View2ViewModel中创建它们但是我没有权限显示主视图?或者,我可以在MainView模型中创建thim但是然后如何在子视图模型中绑定它们(我根据mvvm建议使用RelayCommand obejct并且它们不会冒泡到父模型.)
我在一个主窗口视图中可以看到两个用户控件,我们称之为MainView,UC1和UC2.每个都有ViewModel MainViewModel,UC1ViewModel,UC2View Model.我在UC1上有一个名为"AddItem"的按钮.它应该在UC2的列表中添加一个项目.设置"AddItemCommand"并绑定到它的当前方法是什么.Command应该在MainViewModel,Uc1ViewModel还是UC2ViewModel?我怎么会和它结合起来.
谢谢你的帮助.
我有一个WPF应用程序,它只包含一个Button和一个Textbox来显示一些输出.当用户单击Button时,会启动一个禁用Button的线程,将东西打印到输出Textbox,然后线程停止(此时我想再次启用Button).
该应用程序似乎正确禁用按钮,以及正确更新文本框.但是,当线程完成时,它总是无法正确地重新启用Button!谁能告诉我我做错了什么?
这是我的xaml的片段:
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" HorizontalAlignment="Center" Command="{Binding ExecuteCommand}">E_xecute</Button>
    <Label Grid.Row="1" Content="Output Window:" HorizontalAlignment="Left"/>
    <TextBlock Grid.Row="2" Text="{Binding Output}"/>
</Grid>
这是我的ViewModel代码(我正在使用Josh Smith的MVVM设计):
public class WindowViewModel : ViewModelBase
{
    private bool _threadStopped;
    private RelayCommand _executeCommand;
    private string _output;
    public WindowViewModel()
    {
        _threadStopped = true;
    }
    public string Output { get { return _output; } set { _output = value; OnPropertyChanged("Output"); } }
    public ICommand ExecuteCommand
    {
        get
        {
            if (_executeCommand == null)
            {
                _executeCommand …我在视图上有一个按钮,它通过RoutedUICommand绑定到ViewModel中定义的命令.
XAML代码摘自视图:
<Button Content="Login" Command="{Binding Login}" />
在View的CodeBehind中,我将ViewModel中的命令绑定添加到视图的绑定集合中:
this.CommandBindings.Add( viewModel.LoginCommandBinding );
ViewModel本身实现了以下命令:
public class LoginViewModel:ViewModelBase
{
    public ICommand Login { get; private set; }
    public CommandBinding LoginCommandBinding { get; private set; }
    public LoginViewModel( ) {
        this.Login = 
            new RoutedUICommand( "Login", "Login", typeof( Window ) );
        this.LoginCommandBinding = 
            new CommandBinding( Login, LoginCommandHandler, CanExecuteHandler );
    }
    void LoginCommandHandler( object sender, ExecutedRoutedEventArgs e ) {
        //Put code here
    }
    void CanExecuteHandler( object sender, CanExecuteRoutedEventArgs e ) {
        return true;
    }
}
因此命令被定义为文本和名称"登录".按钮本身的内容为"登录".有没有办法使用命令的文本作为按钮的内容?
以前我一直在使用
this.CommandBindings.Add(
    new CommandBinding(ApplicationCommands.Copy, this.cmdCopy_Executed, this.cmdCopy_CanExecute))
其中cmdCopy_Executed是一个非静态函数,但我见过人们使用
static MyControl()
    {
        CommandBinding binding =
            new CommandBinding(ApplicationCommands.Save, CommandHandler);
        CommandManager.RegisterClassCommandBinding(typeof(MyControl), binding);
    }
 private static void CommandHandler(object target, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("Command Handled!");
    }
CommandBinding是静态的.一个优先于另一个?
我有一个ListBox,ItemTemplate绑定到我的项目的ObservableCollection.目前,我正在尝试实现剪切/复制/粘贴/选择所有(为了简短起见,我只会在这里显示selectall ...)
<UserControl.CommandBindings>
    <CommandBinding Command="SelectAll" CanExecute="SelectAll_CanExecute" Executed="SelectAll_Executed"/>
</UserControl.CommandBindings>
<ListBox x:Name="listbox" 
         ItemsSource="{Binding}" 
         Background="Transparent" 
         SelectionMode="Extended"
         ScrollViewer.VerticalScrollBarVisibility="Auto">
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Command="SelectAll" />
        </ContextMenu>
    </ListBox.ContextMenu>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Background="Transparent">
                <CheckBox Name="cbEnabled" IsChecked="{Binding Enabled, Mode=TwoWay}" Margin="0,2,0,0"/>
                <TextBlock Text="{Binding Name}" Padding="5,0,0,0"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
这是canexecute的代码隐藏:
    private void SelectAll_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = listbox.Items.Count > 0;
        e.Handled = true;
    }
当我第一次运行程序并右键单击列表框时,始终禁用"全选"上下文菜单(并且从不调用SelectAll_CanExecute),直到我选择了某些内容.有没有什么方法可以让它像它应该的那样工作?(并且无需自动选择第一项或让用户必须这样做)
谢谢!
我有使用CommandBinding的控件(WPF),它的注册方式如下:
CommandBinding binding = new CommandBinding(ApplicationCommands.Delete, OnDeleteExecuted, CanExecuteDelete);
CommandManager.RegisterClassCommandBinding(typeof(MyObject), binding);
因此,当我卸载控件时,我想清除此绑定。我将如何处理?
谢谢!
我来自第三方控制.它正在实现ApplicationCommands.SelectAll.但是我想要的行为略有不同.没有我可以覆盖的虚方法,当我注册类处理程序时,就像这样
     CommandManager.RegisterClassCommandBinding(typeof(MyDerivedControl), new CommandBinding(ApplicationCommands.SelectAll, new ExecutedRoutedEventHandler(OnExecutedSelectAll), new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll)));
我的方法没有被调用.我得出的第三方控制是标记
e.Handled=true;
在它的命令处理程序(我知道这个原因,我已经看到了源,但我不能修改它)
我能做什么?
我正在使用MvvmCross,但这可能是一般的命令绑定.
当用户单击按钮时,应用程序需要额外的输入数据才能继续执行我想要在实际命令中执行的操作.我无法在ViewModel中调用UI操作的问题,因此仅绑定MvxCommand(或任何ICommand)将无法正常工作.
有人可能会问为什么:1)我没有在UI上输入输入,用户可以在点击按钮之前输入数据 - >我没有空间.2)制作默认数据,让用户稍后更改 - >这是我的第一个,但用户往往忘记稍后更改!!
那么有人可以提出解决方案吗?我唯一能想到的就是忘记命令绑定,然后让代码弹出ui以获取额外的数据,然后在视图模型中调用一个方法!
谢谢