0

I want to pass the webview2 control on the page to the ViewModel after clicking the button. The following is part of the code for xaml:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <StackPanel>
        <!--Click the button "Button_single", and the value of parameter can be obtained from ViewModel as Microsoft.Web.WebView2.Wpf.WebView2 type-->
        <Button Command="{Binding BtnCommand1}" CommandParameter="{Binding ElementName=webView_single}">Button_single</Button>
        <!--Click the button "Button_list", and the value of parameter obtained from ViewModel is null. Why?-->
        <Button Command="{Binding BtnCommand1}" CommandParameter="{Binding ElementName=webView_list}">Button_list</Button>
        <webview2:WebView2 Name="webView_single" Source="https://www.google.com/" Grid.Row="1">
            <behaviour:Interaction.Triggers>
                <behaviour:EventTrigger EventName="NavigationCompleted">
                    <behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
                </behaviour:EventTrigger>
            </behaviour:Interaction.Triggers>
        </webview2:WebView2>
    </StackPanel> 
    <ScrollViewer Grid.Row="2" >
        <ItemsControl Grid.Row="1" ItemsSource="{Binding AccountDtos}" HorizontalAlignment="Center">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <md:TransitioningContent OpeningEffect="{md:TransitionEffect Kind=ExpandIn}" >
                        <Grid Width="600" MinHeight="800" MaxHeight="250" Margin="8" >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto" />
                                <RowDefinition />
                            </Grid.RowDefinitions>  
                            <Border CornerRadius="4" Grid.RowSpan="5" Background="#7F7F7F" />
                            <StackPanel Orientation="Horizontal">                                   
                                <TextBlock Text="UserName:" />
                                <TextBlock Padding="5,0" Text="{Binding UserName}"  />
                                <TextBlock Text="Password:" />
                                <TextBlock Padding="5,0" Text="{Binding Password}" /> 
                            </StackPanel>
                            <webview2:WebView2 Name="webView_list" Source="https://www.google.com/" Grid.Row="1">
                                <behaviour:Interaction.Triggers>
                                    <behaviour:EventTrigger EventName="NavigationCompleted">
                                        <behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
                                    </behaviour:EventTrigger>
                                </behaviour:Interaction.Triggers>
                            </webview2:WebView2>
                        </Grid>
                    </md:TransitioningContent>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>

I want to pass the webview2 control on the page to the ViewModel after clicking the button. The following is part of the code for xaml:

 public DelegateCommand<object> BtnCommand1 { get => new DelegateCommand<object>(Execute1); }
    private void Execute1(object parameter)
    {
        //In the xaml page, if you click the button "Button_single", you can get the parameter value of Microsoft.Web.WebView2.Wpf.WebView2 type
        //If you click the button "Button_list", the value of parameter is null. Why and how can it not be null?
        Console.Write(parameter);
    }

I want to get the webView control in the list control in the ViewModel. How should I write this code?

(This question Passing a Different button in Command Parameter Wpf Similar to my question, but different)

xj7799911
  • 23
  • 2
  • 7

1 Answers1

0

There are two reasons the webView_list commandparameter cannot work.

The first is conceptual. There are going to be a list of those WebView2s rather than just one. How's it supposed to know which one it is to reference?

You know if you have a list of anything in c# then you'd have to reference by index or something which one in the list you want.

The same would be true for xaml. You'd need to tell it to go look at row 0 or 1 or 2 or whatever.

There is another complication though. WPF has the concept of namescopes. All the controls directly in the grid of your window are in the same namescope.

When you have templates and in particular lists of things that becomes a bit more complicated.

Let's think about this from the bottom up though.

You've named a control webView_list. This is in an itemtemplate. So when you have 4 items you will have 4 WebView2s. But it will not error. Somehow those 4 named controls do not collide with one another.

This is because each of those items produced from that itemtemplate have their own namescope. The first item has a namescope of it's own, the second has it's own namescope etc.

You cannot just use elementname to reference something in a different namescope. So you can't get at a specific webview2 in that list using elementname from outside the item it's in.

In any case, you need some way to tell which item.

You could use selecteditem if this was a listbox.

An itemscontrol has no selection though. To get at your webview2 in an item the usual thing to do would be to put the button in the itemtemplate and the same namescope. That could then use relativesource to get to the command in the parent datacontext. Something like:

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <md:TransitioningContent OpeningEffect="{md:TransitionEffect Kind=ExpandIn}" >
                    <Grid Width="600" MinHeight="800" MaxHeight="250" Margin="8" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>  
                        <Border CornerRadius="4" Grid.RowSpan="5" Background="#7F7F7F" />
                        <StackPanel Orientation="Horizontal">                                   
                            <TextBlock Text="UserName:" />
                            <TextBlock Padding="5,0" Text="{Binding UserName}"  />
                            <TextBlock Text="Password:" />
                            <TextBlock Padding="5,0" Text="{Binding Password}" /> 
                        </StackPanel>
        <Button Command="{Binding DataContext.BtnCommand1, RelativeSource={RelativeSource AncestorType ItemsControl}}"
   CommandParameter="{Binding ElementName=webView_list}"  Grid.Row="2">Button_list</Button>

                        <webview2:WebView2 Name="webView_list" Source="https://www.google.com/" Grid.Row="2">
                            <behaviour:Interaction.Triggers>
                                <behaviour:EventTrigger EventName="NavigationCompleted">
                                    <behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
                                </behaviour:EventTrigger>
                            </behaviour:Interaction.Triggers>
                        </webview2:WebView2>
                    </Grid>
                </md:TransitioningContent>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
Andy
  • 11,864
  • 2
  • 17
  • 20