wpf 如何在列表控件中获取webview2控件

nc1teljy  于 2023-02-05  发布在  其他
关注(0)|答案(1)|浏览(243)

我想在点击按钮后将页面上的webview2控件传递给ViewModel。以下是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>

我想在点击按钮后将页面上的webview2控件传递给ViewModel。以下是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);
    }

我想在ViewModel中的list控件中获取webView控件,应该如何编写这段代码?
(This问题Passing a Different button in Command Parameter Wpf与我的问题类似,但不同)

0yg35tkg

0yg35tkg1#

webView_list命令参数无法工作的原因有两个。
第一个是概念性的。将会有一个WebView2的列表,而不仅仅是一个。它怎么知道它要引用哪一个?
你知道,如果你有一个c#的列表,那么你必须通过索引或者其他东西来引用列表中你想要的东西。
对于xaml来说也是一样,你需要告诉它去看第0行,第1行,第2行或者别的什么。
不过还有另一个复杂之处。WPF有命名范围的概念。所有直接位于窗口网格中的控件都在同一个命名范围中。
当你有模板,特别是列表的东西,变得有点复杂。
让我们从下往上想一想。
你已经命名了一个控件webView_list。这是在一个项目模板中。所以当你有4个项目时,你将有4个WebView2。但是它不会出错。不知何故,这4个命名的控件不会相互冲突。
这是因为从itemtemplate生成的每一个条目都有自己的命名范围,第一个条目有自己的命名范围,第二个条目有自己的命名范围,以此类推。
你不能只使用elementname来引用不同命名空间中的东西,所以你不能使用elementname从它所在的项目之外获取列表中的特定webview2。
在任何情况下,您都需要某种方法来区分是哪一项。
如果这是一个列表框,你可以使用selecteditem。
不过itemscontrol没有selection,要在一个项目中获取webview2,通常要做的事情是将按钮放在itemtemplate和相同的namescope中,然后可以使用relativesource来获取父数据上下文中的命令,类似于:

<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>

相关问题