ملزمة للأسلاف من داخل موارد
-
20-09-2019 - |
سؤال
كيف يمكنني ربط ملف UserControl
خاصية من داخلها ResourceDictionary
؟ أريد كائنًا أعلن في مواردي أن يكون له نفس الشيء DataContext
كما UserControl
واردة في:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Some.Namespace"
DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<local:SomeClass
x:Key="SomeClass"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
</UserControl.Resources>
</UserControl>
في وقت التشغيل ، أحصل على الخطأ:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext; DataItem=null; target element is 'SomeClass' (Name=''); target property is 'DataContext' (type 'Object')
المحلول
كان الحل الخاص بي هو تعيين DataContext
من المورد في الكود behind.
.xaml
<local:SomeType x:Key="SomeKey" SomeProperty="{Binding ... }" />
.xaml.cs
public SomeControl()
{
InitializeComponent();
((SomeType)this.Resources["SomeKey"]).DataContext = this;
}
نصائح أخرى
عند استخدام FindanCestor ، يحتاج العنصر المستهدف إلى أن يكون نسلًا (إما منطقيًا أو بصريًا) للمصدر. لا يظهر كائنك في الشجرة المرئية أو المنطقية ، فهو ببساطة في الموارد. لذلك لا يمكنك استخدام الأقارب مع FindanCestor لكائنك.
يمكنك استخدام elementName في الربط الخاص بك رغم ذلك. شيء من هذا القبيل يجب أن تعمل:
<UserControl x:Name="userControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Some.Namespace"
DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<local:SomeClass
x:Key="SomeClass"
DataContext="{Binding Path=DataContext, ElementName=userControl}" />
</UserControl.Resources>
</UserControl>
جلس X: مشترك= "خطأ" ، سيستنسخ هذا المورد على كل استخدام ويجعله طفلاً من العنصر ، مما يتيح استخدام الارتباطات.
<local:SomeClass
x:Key="SomeClass"
x:Shared="False"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
أعتقد أن ما تبحث عنه هو مجرد {binding} الذي يرتبط بـ DataContext الموروثة. فيما يلي مثال ، على الرغم من أن الغريب يوضح كيف يمكنك الحصول على لون من خلال الارتباط بـ DataContext:
<Window x:Class="AncestorBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Blue" />
</Window.Resources>
<StackPanel>
<Button DataContext="{Binding Source={StaticResource MyBrush}}" Content="My Button">
<Button.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{Binding}" />
</Style>
</Button.Resources>
</Button>
</StackPanel>
</Window>
ما أود فعله هو إنشاء سلوك متصل (سياق SourSourceBehavior) على عنصر تحكم المستخدم ، وتحديد مفتاح الموارد على هذا السلوك المرفق. سوف يبحث السلوك في المورد (لست متأكدًا من أنك ستتمكن من القيام بذلك عند إرفاقه ، إذا لم يكن الأمر كذلك ، فستحتاج إلى ربط حدث محمّل) ونقل سياق البيانات.
عند إضافة موردك إلى الشجرة المرئية ، يجب أن يرث سياق البيانات. لكن ... ألق نظرة على جاسوس العنصر قد تفعل فقط ما تحتاجه.