Wpf 为什么ItemsControl中ContentControl的TargetNullValue在项之间共享?

Wpf 为什么ItemsControl中ContentControl的TargetNullValue在项之间共享?,wpf,xaml,data-binding,itemscontrol,mahapps.metro,Wpf,Xaml,Data Binding,Itemscontrol,Mahapps.metro,鉴于此xaml: <ItemsControl Grid.Row="1" ItemsSource="{Binding Devices}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Rows="1" /> </ItemsPanelTemplate>

鉴于此xaml:

    <ItemsControl Grid.Row="1" ItemsSource="{Binding Devices}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="1" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewModels:IDeviceViewModel}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Name}"
                               Grid.Row="0"
                               Margin="5"
                               HorizontalAlignment="Center" />
                    <ContentControl Grid.Row="1">
                        <ContentControl.Content>
                            <Binding Path="CurrentState">
                                <Binding.TargetNullValue>
                                    <Button Command="{Binding DataContext.ActivateCommand, RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}}"
                                            CommandParameter="{Binding}">
                                        <Button.Template>
                                            <ControlTemplate>
                                                <Image MaxWidth="100"
                                                       Margin="10"
                                                       HorizontalAlignment="Center"
                                                       VerticalAlignment="Center"
                                                       Source="/Resources/ActivateDevice.png" />
                                            </ControlTemplate>
                                        </Button.Template>
                                    </Button>
                                </Binding.TargetNullValue>
                            </Binding>
                        </ContentControl.Content>
                    </ContentControl>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

所以现在的问题是:为什么首先要共享TargetNullValue?

该属性告诉WPF在每次使用XAML元素时创建一个新实例,但这只能在ResourceDictionary中的项上设置。尝试将按钮放入带有x:Shared='False'的ResourceDictionary中,然后使用StaticResource引用它。

一个想法:将按钮放入带有x:Shared='False'的ResourceDictionary中。然后使用“StaticResource”引用资源。@KeithStein这实际上是可行的!它还提供了一个简洁的语法,因为绑定仍然是一个属性。然而,我真的很想理解为什么wpf首先要这么做。我的意思是,我希望items控件中各个项的数据模板能够独立实例化,它们如何在每个项的实例中共享内容控件中绑定的目标空值?太好了。我把它贴了出来,作为你可以接受的答案。至于为什么会出现这种情况:我确实希望每个项都有自己的DataTemplate实例,但这些属性设置为的值可能会被重用?因此,每个单独的TargetNullValue都会被分配到已解析的相同按钮。这适用于最常用的字符串或其他值类型,可以节省时间和内存,但会给大多数其他类带来问题。
    <ItemsControl Grid.Row="1" ItemsSource="{Binding Devices}">
        <ItemsControl.Resources>
            <Button x:Key="ActivateDeviceButton"
                    x:Shared="False"
                    Command="{Binding DataContext.ActivateCommand, RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}}"
                    CommandParameter="{Binding Path=DataContext, ElementName=deviceRoot}">
                <Button.Template>
                    <ControlTemplate>
                        <Image MaxWidth="100"
                               Margin="10"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Source="/Resources/ActivateDevice.png" />
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </ItemsControl.Resources>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="1" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewModels:IDeviceViewModel}">
                <Grid x:Name="deviceRoot">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Name}"
                               Grid.Row="0"
                               Margin="5"
                               HorizontalAlignment="Center" />
                    <ContentControl Grid.Row="1" Content="{Binding CurrentState, TargetNullValue={StaticResource ActivateDeviceButton}}" />
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>