您的位置:首页 > 其它

modify the visual tree at runtime

2013-04-26 00:00 274 查看
you may find sometime that you nee to alter the visual tree or the logical tree at runtime ot change some behavior, well this is not straight forward as it looks .

But a general rule that you have is that the Logical tree structure construct before the visual tree structure, which means that you can inject some methods to at the earlier stage of Visual Streee construction, where you have the logical tree in place, and then with the logical tree strucure in hand, you can start to make some changes to the visual tree.

here is some code where it shows given a structure like this:

<UserControl>
<UserControl.Resources>
<Resources.MergedDictionaryResource>
<Resource Source=".../>
</Resources.MergedDictionaryResource>
<UserControl>
</UserControl>
</UserControl>
Where you want to remove some resource from the first UserControl, here is some code that shows you how to do that.

public partial class SearchResultsView : UserControl
{
public SearchResultsView()
{
InitializeComponent();
}

protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
if (oldParent == null) // creation when oldParent == null
{
RemoveOnyxDarkTheme();

Trace.WriteLine("UIElement.UpdateLayout ... ");
UpdateLayout();
}
else
{
Trace.WriteLine("oops!!");
}
//InvalidateArrange();
//base.OnVisualParentChanged(oldParent);
//InvalidateVisual();
//this.UpdateLayout();
}

private void RemoveOnyxDarkTheme()
{
DependencyObject parent = this.Parent;
parent = GetLogicalParent<UserControl>(parent);
if (parent != null)
{
var userControl = parent as UserControl;
var list = new List<ResourceDictionary>();
if (userControl != null)
{
foreach (var item in userControl.Resources.MergedDictionaries)
{
try
{
if (!string.IsNullOrEmpty(item.Source.OriginalString) && item.Source.OriginalString.Contains("Nomura.Desktop.Themes.OnyxDark.DevExpress"))
{
list.Add(item);
}
else
{
if (string.IsNullOrEmpty(item.Source.OriginalString))
{
Trace.WriteLine("Wrong pack URI??");
}
}
}
catch (Exception ex)
{
Trace.WriteLine("Caught Exception, silently ignore : " + ex.ToString());
}
}

foreach (var item in list)
{
userControl.Resources.MergedDictionaries.Remove(item);
}
}
}
}

private static DependencyObject GetParent(DependencyObject dObj)
{
if (dObj != null) return VisualTreeHelper.GetParent(dObj);
return null;
}

private static DependencyObject GetParent(DependencyObject dObj, Type type)
{
if (dObj != null&& type != null)
{
while (GetParent(dObj) != null && GetParent(dObj).GetType() != type)
dObj = GetParent(dObj);
return dObj;
}
return null;
}

private static DependencyObject GetParent<T>(DependencyObject dObj)
{
return GetParent(dObj, typeof (T));
}

private static DependencyObject GetLogicalParent(DependencyObject dObj)
{
if (dObj != null) return LogicalTreeHelper.GetParent(dObj);
return null;
}

private static DependencyObject GetLogicalParent(DependencyObject dObj, Type type)
{
if (dObj != null && type != null)
{
while (GetLogicalParent(dObj) != null && GetLogicalParent(dObj).GetType() != type)
dObj = GetLogicalParent(dObj);
return dObj;
}
return null;
}

private static DependencyObject GetLogicalParent<T>(DependencyObject dObj)
{
return GetLogicalParent(dObj, typeof(T));
}
}
AS you can see the key is the OnVisualChanged method, which fires when the Visual Parent change (when it is created on the visual tree) , then you can grab the parent node and start cracking on .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐