簡體   English   中英

觸發綁定到子控件不起作用

[英]Trigger Binding to Child Control Not Working

我在 WPF Window 上有這個

<local:TestControl>
    <local:TestHost />
</local:MediaPlayer>

像這樣定義的類

public class TestControl : ContentControl
{
    static TestControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(TestControl), new FrameworkPropertyMetadata(typeof(TestControl)));
        ContentProperty.OverrideMetadata(typeof(TestControl), new FrameworkPropertyMetadata(ContentChanged, CoerceContent));
    }

    private static void ContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var P = d as TestControl;
        P.Host = e.NewValue as TestHost;
    }

    private static object CoerceContent(DependencyObject d, object baseValue) => baseValue as TestHost;

    public static readonly DependencyPropertyKey HostProperty = DependencyProperty.RegisterReadOnly("Host", typeof(TestHost), typeof(TestControl), null);
    public TestHost Host { get => (TestHost)GetValue(HostProperty.DependencyProperty); protected set => SetValue(HostProperty, value); }
}

public class TestHost : Control
{
    static TestHost()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(TestHost), new FrameworkPropertyMetadata(typeof(TestHost)));
    }

    public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register("IsPlaying", typeof(bool), typeof(TestHost), 
        new PropertyMetadata(true));
    public bool IsPlaying { get => (bool)GetValue(IsPlayingProperty); set => SetValue(IsPlayingProperty, value); }
}

然后在 Generic.xaml

<Style TargetType="{x:Type local:TestControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TestControl}">
                <Border>
                    <Grid>
                        <ContentPresenter Content="{TemplateBinding Content}" />
                        <Button x:Name="MyButton" Content="False" />
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <DataTrigger Value="True" Binding="{Binding Host.IsPlaying, RelativeSource={RelativeSource TemplatedParent}}">
                        <Setter TargetName="MyButton" Property="Content" Value="True" />
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

它應該在按鈕中顯示“true”,但仍然是“false”。

在設置主機時設置斷點,它確實被調用並且主機確實設置正確。

在更改 VS 選項以顯示所有綁定調試信息后,我在調試日志中得到了這個。

System.Windows.Data Information: 41 : BindingExpression path error: 'Host' property not found for 'object' because data item is null.  This could happen because the data provider has not produced any data yet. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Host.IsPlaying; DataItem=null; target element is 'TestControl' (Name=''); target property is 'NoTarget' (type 'Object')

請注意,在觸發器之外創建正常綁定確實有效

<Button x:Name="MyButton" Content="{Binding Host.IsPlaying, RelativeSource={RelativeSource TemplatedParent}}" />

我怎樣才能讓這個觸發器綁定工作?

嗯......這是“一種”方式

<Style TargetType="{x:Type local:TestControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TestControl}">
                <Border>
                    <Grid>
                        <ContentPresenter Content="{TemplateBinding Content}" />
                        <Button x:Name="MyButton" Content="False" Height="50" Width="100" />
                        <TextBox x:Name="IsPlayingHidden" Visibility="Hidden" Text="{Binding Host.IsPlaying, RelativeSource={RelativeSource TemplatedParent}}" />
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="IsPlayingHidden" Property="Text" Value="True">
                        <Setter TargetName="MyButton" Property="Content" Value="True" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

這有效,但它很丑。

它真的看起來像框架中的一個錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM