FindAncestor WPF , , , . Visual, , , , . , FrameworkContentElement, . , ElementHost, , .
, - . , .
, , , updateFunction. updateFunction , , .
static void UpdateBindings(Visual visual, Func<Binding, Binding> updateFunction)
{
if(visual==null) return;
for(int i=0; i<VisualTreeHelper.GetChildrenCount(visual); i++)
UpdateBindings(VisualTreeHelper.GetChild(visual, i) as Visual, updateFunction);
for(var enumerator = visual.GetLocalValueEnumerator(); enumerator.MoveNext(); )
{
var property = enumerator.Current.Property;
var binding = BindingOperations.GetBinding(visual, property);
if(binding==null) continue;
var newBinding = updateFunction(binding);
if(newBinding!=binding)
BindingOperations.SetBinding(visual, property, newBinding);
}
}
, , , AncestorType RelativeSource FindAncestor :
static void ReplaceFindAncestorType(Visual visual, Type fromType, Type toType)
{
UpdateBindings(visual, binding =>
binding.RelativeSource.Mode != RelativeSourceMode.FindAncestor ? binding :
binding.RelativeSource.AncestorType != fromType ? binding :
new Binding
{
RelativeSource = new RelativeSource(
RelativeSourceMode.FindAncestor,
toType,
binding.RelativeSource.AncestorLevel),
Path = binding.Path,
Mode = binding.Mode,
Converter = binding.Converter,
StringFormat = binding.StringFormat,
UpdateSourceTrigger = binding.UpdateSourceTrigger,
});
}
, .
ReplaceFindAncestorVisualType :
elementHost.LayoutUpdated += (obj, e) =>
{
ReplaceFindAncestorType(elementHost, typeof(Window), typeof(ElementHost);
};
: IsActive ElementHost, . , , , RelativeSource. , :
elementHost.LayoutUpdated += (obj, e) =>
{
UpdateBindings(elementHost, binding =>
binding.RelativeSource.AncestorType != typeof(Window) ? binding :
new Binding
{
Source = ultimateContainingWindowOrOtherObjectHavingIsActiveProperty,
Path = new PropertyPath("IsActive"), // Put property name here
});
};
, , FindAncestor: - , . .
, : , ElementHost, . , , , ActiveWindow, ForegroundWindow, Z Order, Minimized state, keyboard focus .. , .