MVVM-Light, firing events from a button inside a data grid column template

后端 未结 3 1549
星月不相逢
星月不相逢 2021-02-06 02:43

MVVM light has been a pleasure to learn, but here I am stuck. The problem is event firing.

In the code below, one button the works and fires events. The other button doe

相关标签:
3条回答
  • 2021-02-06 03:05

    Your data context is lost in the DataGrid DataGridTemplateColumn since the DataGrid.Columns isn't a dependency property. Because of this, you can't use element-to-element data binding from within your DataGridTemplateColumn.

    However, this is easily fixed thanks to MVVM Light Toolkit's ViewModelLocator.

    I don't know what your ViewModel is called, but assuming it is MainViewModel you can change your button binding to this:

    <sdk1:DataGridTemplateColumn Header="Edit">
        <sdk1:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Button Content="THIS BUTTON WILL WORK NOW ;-)" >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <Command:EventToCommand Command="{Binding Source={StaticResource Locator},
                                                                      Path=MainViewModel.HandleEditQuestionActionCommand}"
                                                    PassEventArgsToCommand="True" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>
            </DataTemplate>
        </sdk1:DataGridTemplateColumn.CellTemplate>
    </sdk1:DataGridTemplateColumn>
    
    0 讨论(0)
  • 2021-02-06 03:09

    The button inside the DataGrid has a DataContext of QuestActions since the Binding is based on the the DataGrid's ItemSource Property. That being the case, you'll need to find the DataContext of the DataGrid itself (or the UserControl or whatever parent that has the Command in it's DataContext) to get to your Command:

    <Command:EventToCommand 
    Command="{Binding RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type sdk1:DataGrid}}, 
    Path=DataContext.ViewSchemaCommand, Mode=OneWay}" 
    PassEventArgsToCommand="True" />
    
    0 讨论(0)
  • 2021-02-06 03:22

    This solution only works for static view models. check out Dan Whalin's page out for an alternative answer. http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

    You can create a resource like so (don't forget your reference):

    <UserControl.Resources>
         <controls:DataContextProxy x:Key="DataContextProxy" />
    </UserControl.Resources>
    

    or

    <sdk:Page.Resources>
        <controls:DataContextProxy x:Key="DataContextProxy"/>
    </sdk:Page.Resources>
    

    Use in control like so:

    <sdk:DataGridTemplateColumn>
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Content="Content">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <cmd:EventToCommand Command="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.MyCommand}"
                                            CommandParameter="{Binding Path=SomeValue}"
                                            PassEventArgsToCommand="False">     
                        </cmd:EventToCommand>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </DataTemplate>
    </sdk:DataGridTemplateColumn.CellTemplate>
    

    ViewModel Define RelayCommand:

    public RelayCommand<object> MyCommand { get; set; }
    

    Set RelayCommand in Constructor:

    MyCommand = new RelayCommand<object>((e) =>
            {
                if (e != null && e is int)
                {
                    int varName = int.Parse(e.ToString());
    
                    //DoSomething...
                }
            });
    
    0 讨论(0)
提交回复
热议问题