簡體   English   中英

(又一個)附加屬性綁定不起作用

[英](Yet another) attached property binding not working

起初我試圖制作 UWP 應用程序,但后來意識到這對我來說限制太大,現在試圖將現有代碼移植到經典 WPF。 I'm using .NET Core 3.1, Caliburn, Kinnara/ModernWpf, Microsoft.NETCore.Windows.ApiSets, Microsoft.Windows.SDK.Contracts and System.Windows.Interactivity.WPF (though, not actually using last one). 因此,基本上,它應該為我提供了對 WPF 的相當順利的移植,但正如我發現的那樣,Caliburn 的附加屬性 View.Model 不起作用。 我嘗試創建自己的附加屬性並將其綁定到 VM 的測試屬性,但它也沒有工作,該屬性永遠不會被訪問,附加屬性的值是 null。

基本代碼如下:

(這不是真實的情況,在實際情況下我在 NavigationView.ContentTemplate 中使用 ContentPresenter,但這種情況在實踐中應該是相同的。並且我已經在外部使用 ContentPresenter 進行了測試,並且將 NavigationView 注釋掉了。另外,如果我d 例如,使用 TextBlock,而不是 ContentPresenter,然后綁定可以正常工作,並且附加屬性的值符合預期。可能有什么問題以及 ContentPresenter 的不同之處是什么?)

視圖模型

    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
    {
        public ShellViewModel()
        {
            ActiveItem = new SomeOtherViewModelDerivedFromScreen();
            Task.Delay(3000).ContinueWith(task => OnPropertyChanged(new PropertyChangedEventArgs("HelloWorld")));
            // This is getting called ok, though AFAIK it's not even necessary to raise PropertyChanged
        }
    ...

        public string HelloWorld => "Hello world"; // Breakpoint here, never gets called
    ...
    }

附屬財產

    public static class Test
    {
        public static readonly DependencyProperty TestProperty = 
            DependencyProperty.RegisterAttached("Test", typeof(object), typeof(Test), 
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, 
                TestChangedCallback));

        public static object GetTest(UIElement element)
        {
            // Breakpoint here, never gets called
            return element.GetValue(TestProperty);
        }

        public static void SetTest(UIElement element, object value)
        {
            // Breakpoint here, never gets called
            element.SetValue(TestProperty, value);
        }
        private static void TestChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Breakpoint here, never gets called
        }
    }

XAML

<Window x:Class="RecipeCalculator.Views.ShellView"
        ... >
    <Grid>
        <ContentPresenter x:Name="TestCP" t:Test.Test="{Binding Path=HelloWorld}" Content="{Binding ActiveItem}"/>
    </Grid>
</Window>

背后的代碼

public partial class ShellView : Window
    {
        public ShellView()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var val = TestCP.GetValue(ViewModels.Test.TestProperty);
            // Breakpoint here, val is null.
        }
    }

您應該將ContentPresenter替換為ContentControl

<ContentControl x:Name="TestCP" t:Test.Test="{Binding Path=HelloWorld}" 
                Content="{Binding ActiveItem}"/>

ContentPresenter僅用於在ControlTemplate中顯示ContentControlContent 它不繼承DataContext ,這就是您的綁定不起作用的原因。

經過大量的測試、試驗和谷歌搜索,我已經弄清楚了。

Kinnara/ModernWpf 使用的是 ContentPresenter,它會刪除 DataContext ,如本文所述 此外,它的 ContentPresenter/ContentControl 沒有在模板中綁定到 ContentTemplate、ContentTemplateSelector 和 ContentStringFormat,因此我設置的 ContentTemplate 從未實際使用過,因為它沒有被控件綁定。 修復源代碼后,一切正常。

暫無
暫無

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

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