【问题标题】:How to use ElementName when binding to UIElement within template?在模板中绑定到 UIElement 时如何使用 ElementName?
【发布时间】:2020-06-11 02:58:36
【问题描述】:

我试图弄清楚在绑定到与我要绑定的项目位于同一模板中的列表框时如何解决使用 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 布尔值为 true。我选择不使用弹出窗口,因为我希望列表框 SelectedItem 在列表关闭时清除,但弹出窗口会保存状态。如果有某种方法可以清除 XAML 中的列表框 SelectedItem(以遵循 MVVM),这也可以解决我的问题。

【问题讨论】:

  • 你为什么要使用 InvokeCommandAction?您还可以将 ListBox 的 SelectedItem 属性绑定到视图模型中的属性,并对属性设置器中的选择更改做出反应。
  • 或者。如果您出于某种原因不喜欢 setter 中的逻辑,则您的命令可能没有参数,但使用绑定的选定项。

标签: c# wpf mvvm data-binding


【解决方案1】:

正如其他人在这里所建议的那样,您应该通过在 ViewModel 上移动由 SelectedItem 属性更改触发的逻辑来替换 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>

【讨论】:

    猜你喜欢
    • 2013-02-23
    • 2015-03-10
    • 2012-07-14
    • 1970-01-01
    • 2012-03-09
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多