在模板中绑定到UIElement时如何使用ElementName?

时间:2020-06-11 02:58:36

标签: c# wpf mvvm data-binding

我试图弄清楚如何绑定到与我要绑定的项目位于同一模板的列表框时使用ElementName的问题。运行下面显示的代码时,出现以下错误:

System.NullReferenceException:“对象引用未设置为对象的实例。”

commandParameter为空。

此外,没有任何迹象表明“调试输出”窗口中存在任何绑定错误。

我尝试使用Binding ElementName inside a DataTemplate中建议的x:Reference方法,但这引发了以下错误:

System.Windows.Markup.XamlParseException:由于存在周期性依赖关系,因此无法调用MarkupExtension.ProvideValue。 MarkupExtension内部的属性无法引用引用MarkupExtension结果的对象

我的代码如下所示:

<ContentControl Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Center" Width="Auto" 
                        Height="Auto" VerticalAlignment="Top" Name="AddDeviceContentControl">
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ChooseNewDevice}" Value="true">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="ContentControl">
                                        <ListBox Name="AddDeviceList" ItemsSource="{Binding Source={StaticResource DeviceTypes}}" >
                                            <ie:Interaction.Triggers>
                                                <ie:EventTrigger EventName="SelectionChanged">
                                                    <ie:InvokeCommandAction 
                                                        Command="{Binding AddDeviceCommand}" 
                                                        CommandParameter="{Binding ElementName=AddDeviceList, Path=SelectedItem}"/>
                                                </ie:EventTrigger>
                                            </ie:Interaction.Triggers>
                                        </ListBox>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>

注意:我在这里使用内容控件和模板,因为我希望列表是不可见的,除非ChooseNewDevice bool为true。我选择不使用弹出窗口,因为我希望在关闭列表时清除列表框SelectedItem,但是弹出窗口会保存状态。如果有某种方法可以清除XAML中的框框SelectedItem(以便遵循MVVM),那也可以解决我的问题。

1 个答案:

答案 0 :(得分:0)

如此处其他人的建议,您应该通过更改SelectedItem属性触发的ViewModel上的逻辑来替换XAML中的交互触发器。

您的XAML会变得更简单,像这样:

<ListBox ItemsSource="{Binding Source={StaticResource DeviceTypes}}" 
     SelectedItem="{Binding SelectedItem}">
    <ListBox.Style>
    <Style TargetType="ListBox">
        <Setter Property="Visibility" Value="Visible"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ChooseNewDevice}" Value="true">
                <Setter Property="Visibility" Value="Hidden"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListBox.Style>