Problemem tutaj ma do czynienia ze sposobem
Style
utworów: w zasadzie, jeden „kopia” z
Style
zostaną utworzone (na pierwszy odnośnik), iw tym momencie, może być wiele
TextBox
kontrole chcesz to
Style
zastosowane do - którego z nich użyje dla RelativeSource?
The (prawdopodobne) odpowiedź jest użycie
Template
zamiast
Style
- ze sterowaniem lub szablonu danych, będziesz w stanie uzyskać dostęp do wizualnego drzewa z
TemplatedParent
, i że powinien dostać cię tam, gdzie trzeba być .
EDYCJA: W przypadku dalszych rozważań, mogę być tu niepoprawny ... Wezmę krótką próbną uprząż, gdy znajdę się z powrotem przed komputerem i zobaczę, czy mogę to udowodnić/obalić.
DALSZA EDYCJA: Chociaż to, co pierwotnie powiedziałem, było prawdopodobnie "prawdziwe", to nie jest twój problem; Co powiedział Raul re: drzewo wizualny jest poprawne:
- ustawiasz właściwość
Background
na TextBox
do instancji VisualBrush
.
- Numer
Visual
tego pędzla jest , a nie odwzorowany na drzewo wizualne kontrolki.
- W rezultacie nawigacja nie powiedzie się, ponieważ obiekt nadrzędny tego wizualnego będzie pusty.
- Jest tak w przypadku, niezależnie od tego, czy jest zadeklarowany jako
Style
lub ControlTemplate
.
- Wszystko to powiedziawszy, poleganie na
ElementName
zdecydowanie nie jest idealne, ponieważ zmniejsza możliwość ponownego użycia definicji.
Co robić?
Ja niszczyłem mój mózg w ciągu nocy, próbując wymyślić sposób, w jaki można poprowadzić kontekst właściwego dziedziczenia do zawartego pędzla, z małym sukcesem ...I nie pochodzić z tego super Hacky sposób, jednakże:
pierwsze, obiekt pomocnika (Uwaga: Zwykle nie mój styl Kod ten sposób, ale starają się zaoszczędzić miejsce):
public class HackyMess
{
public static String GetCaption(DependencyObject obj)
{
return (String)obj.GetValue(CaptionProperty);
}
public static void SetCaption(DependencyObject obj, String value)
{
Debug.WriteLine("obj '{0}' setting caption to '{1}'", obj, value);
obj.SetValue(CaptionProperty, value);
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.RegisterAttached("Caption", typeof(String), typeof(HackyMess),
new FrameworkPropertyMetadata(null));
public static object GetContext(DependencyObject obj) { return obj.GetValue(ContextProperty); }
public static void SetContext(DependencyObject obj, object value) { obj.SetValue(ContextProperty, value); }
public static void SetBackground(DependencyObject obj, Brush value) { obj.SetValue(BackgroundProperty, value); }
public static Brush GetBackground(DependencyObject obj) { return (Brush) obj.GetValue(BackgroundProperty); }
public static readonly DependencyProperty ContextProperty = DependencyProperty.RegisterAttached(
"Context", typeof(object), typeof(HackyMess),
new FrameworkPropertyMetadata(default(HackyMess), FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior | FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.RegisterAttached(
"Background", typeof(Brush), typeof(HackyMess),
new UIPropertyMetadata(default(Brush), OnBackgroundChanged));
private static void OnBackgroundChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var rawValue = args.NewValue;
if (rawValue is Brush)
{
var brush = rawValue as Brush;
var previousContext = obj.GetValue(ContextProperty);
if (previousContext != null && previousContext != DependencyProperty.UnsetValue)
{
if (brush is VisualBrush)
{
// If our hosted visual is a framework element, set it's data context to our inherited one
var currentVisual = (brush as VisualBrush).GetValue(VisualBrush.VisualProperty);
if(currentVisual is FrameworkElement)
{
(currentVisual as FrameworkElement).SetValue(FrameworkElement.DataContextProperty, previousContext);
}
}
}
// Why can't there be just *one* background property? *sigh*
if (obj is TextBlock) { obj.SetValue(TextBlock.BackgroundProperty, brush); }
else if (obj is Control) { obj.SetValue(Control.BackgroundProperty, brush); }
else if (obj is Panel) { obj.SetValue(Panel.BackgroundProperty, brush); }
else if (obj is Border) { obj.SetValue(Border.BackgroundProperty, brush); }
}
}
}
A teraz zaktualizowane XAML:
<Style x:Key="CueBannerTextBoxStyle"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="TextBox.Text"
Value="{x:Static sys:String.Empty}">
<Setter Property="local:HackyMess.Background">
<Setter.Value>
<VisualBrush AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(local:HackyMess.Caption)}"
Foreground="LightGray"
Background="White"
Width="200" />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="local:HackyMess.Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<TextBox x:Name="txtProductInterfaceStorageId"
local:HackyMess.Caption="myCustomCaption"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
<TextBox x:Name="txtProductInterfaceStorageId2"
local:HackyMess.Caption="myCustomCaption2"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
Dobra, spróbuję - daj mi znać, jeśli Ci się uda! Dzięki – glasswall
Pozdrawiam za badania, dam mu wir .. – glasswall