C# 如何在项目中重用xaml命名空间定义
我修改了这个问题,以便更详细地说明重用xaml定义的含义C# 如何在项目中重用xaml命名空间定义,c#,wpf,xaml,C#,Wpf,Xaml,我修改了这个问题,以便更详细地说明重用xaml定义的含义 <UserControl x:Class="XamlDemo.ControlA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://
<UserControl x:Class="XamlDemo.ControlA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlDemo"
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
mc:Ignorable="d">
<!--
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
foo and bar will tend to repeat in exactly this constellation all over the project.
If one of these namespaces changes all xaml files need to be edited.
I would like to include a different file as a component where i would only write foo and bar once
-->
<StackPanel>
<foo:ExtTextBlock></foo:ExtTextBlock>
<bar:ExtLabel></bar:ExtLabel>
</StackPanel>
</UserControl>
<UserControl x:Class="XamlDemo.ControlB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlDemo"
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
mc:Ignorable="d" >
<StackPanel>
<foo:ExtTextBox></foo:ExtTextBox>
<bar:ExtButton></bar:ExtButton>
</StackPanel>
</UserControl>
两者都使用我的本地名称空间声明。我希望它们包含对不同xaml的引用,并从中获取名称空间
我没有找到任何方法来做到这一点——这里有一些概念代码,说明了我想象中的情况。显然,这不会编译
<magic
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar">
</magic>
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns="get it from magic">
</UserControl>
基本控制:
namespace WpfApplication9
{
public class BaseControl : UserControl
{
public BaseControl()
{
}
public override void EndInit()
{
base.EndInit();
ExtTextBlock block = new ExtTextBlock { Width = 100 , Height = 20 , Text = "Test Block" };
ExtButton button = new ExtButton { Width = 100, Height = 20 , Content = "ClickMe"};
ExtLabel label = new ExtLabel { Width = 100, Height = 30 ,Content = "Test Label"};
ExtTextBox txtBox = new ExtTextBox { Width = 100, Height = 20 ,Text= "Hi There"};
Grid g = (Grid)BaseControl.FindChild(this, "gridMain");
g.Children.Add(button);
g.Children.Add(block);
g.Children.Add(label);
g.Children.Add(txtBox);
Grid.SetRow(block, 0);
Grid.SetRow(button, 1);
Grid.SetRow(label, 2);
Grid.SetRow(txtBox, 3);
button.Click += button_Click;
}
void button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hi There");
}
public static DependencyObject FindChild(DependencyObject parent, string name)
{
// confirm parent and name are valid.
if (parent == null || string.IsNullOrEmpty(name)) return null;
if (parent is FrameworkElement && (parent as FrameworkElement).Name == name) return parent;
DependencyObject result = null;
if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate();
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
result = FindChild(child, name);
if (result != null) break;
}
return result;
}
/// <summary>
/// Looks for a child control within a parent by type
/// </summary>
public static T FindChild<T>(DependencyObject parent)
where T : DependencyObject
{
// confirm parent is valid.
if (parent == null) return null;
if (parent is T) return parent as T;
DependencyObject foundChild = null;
if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate();
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
foundChild = FindChild<T>(child);
if (foundChild != null) break;
}
return foundChild as T;
}
}
}
namespace WpfApplication9.Foo
{
public class ExtTextBlock : TextBlock { }
public class ExtTextBox : TextBox { }
}
namespace WpfApplication9.Bar
{
public class ExtButton : Button { }
public class ExtLabel : Label { }
}
命名空间WpfApplication9
{
公共类BaseControl:UserControl
{
公共基站控制()
{
}
公共重写void EndInit()
{
base.EndInit();
ExtTextBlock=newexttextblock{Width=100,Height=20,Text=“Test block”};
ExtButton=新建ExtButton{Width=100,Height=20,Content=“ClickMe”};
ExtLabel label=newextlabel{Width=100,Height=30,Content=“Test label”};
ExtTextBox txtBox=newexttextbox{Width=100,Height=20,Text=“Hi There”};
Grid g=(Grid)BaseControl.FindChild(这是“gridMain”);
g、 添加(按钮);
g、 添加(块);
g、 添加(标签);
g、 添加(txtBox);
Grid.SetRow(块,0);
Grid.SetRow(按钮,1);
Grid.SetRow(标签2);
Grid.SetRow(txtBox,3);
按钮。单击+=按钮\u单击;
}
无效按钮\单击(对象发送器,路由目标)
{
MessageBox.Show(“你好”);
}
公共静态DependencyObject FindChild(DependencyObject父对象,字符串名称)
{
//确认父项和名称有效。
if(parent==null | | string.IsNullOrEmpty(name))返回null;
if(parent为FrameworkElement&(parent为FrameworkElement).Name==Name)返回parent;
DependencyObject结果=null;
if(parent是FrameworkElement)(parent是FrameworkElement).ApplyTemplate();
int childrenCount=visualtreeheloper.GetChildrenCount(父级);
for(int i=0;i
控制1。xaml
<base:BaseControl x:Class="WpfApplication9.Control1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:WpfApplication9"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="gridMain">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
</Grid>
您可以在创建Control1时创建Control2类。
正如我所说,xaml固有性是不可能的。正如所述,xaml继承是不可能的。无论如何,您可以考虑使用以减少和清除命名空间定义。
<UserControl x:Class="XamlDemo.ControlA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlDemo"
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
mc:Ignorable="d">
<!--
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
foo and bar will tend to repeat in exactly this constellation all over the project.
If one of these namespaces changes all xaml files need to be edited.
I would like to include a different file as a component where i would only write foo and bar once
-->
<StackPanel>
<foo:ExtTextBlock></foo:ExtTextBlock>
<bar:ExtLabel></bar:ExtLabel>
</StackPanel>
</UserControl>
<UserControl x:Class="XamlDemo.ControlB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlDemo"
xmlns:foo="clr-namespace:XamlDemo.Foo"
xmlns:bar="clr-namespace:XamlDemo.Bar"
mc:Ignorable="d" >
<StackPanel>
<foo:ExtTextBox></foo:ExtTextBox>
<bar:ExtButton></bar:ExtButton>
</StackPanel>
</UserControl>
您可以找到一篇关于CodeProject的有趣文章
实际上,如果要包含在XAML中的名称空间位于引用的程序集中,则可以轻松地将它们映射到单个URI中。只需以以下方式在引用的程序集中添加XmlnsDefinition
属性:
[assembly: XmlnsDefinition("urn:johannes-ui-controls", "XamlDemo.Foo")]
[assembly: XmlnsDefinition("urn:johannes-ui-controls", "XamlDemo.Bar")]
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:uiControls="urn:johannes-ui-controls">
<StackPanel>
<uiControls:ExtTextBox />
<uiControls:ExtButton />
</StackPanel>
</UserControl>
等等
然后在XAML中,您可以这样使用它们:
[assembly: XmlnsDefinition("urn:johannes-ui-controls", "XamlDemo.Foo")]
[assembly: XmlnsDefinition("urn:johannes-ui-controls", "XamlDemo.Bar")]
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:uiControls="urn:johannes-ui-controls">
<StackPanel>
<uiControls:ExtTextBox />
<uiControls:ExtButton />
</StackPanel>
</UserControl>
此解决方案的限制是不能对包含XAML的程序集使用XmlnsDefinition
属性。
也许这并不是你想要的,但也许它可以帮助你。XAML名称空间在某种程度上是特殊的吗?如果它遵循正常的XML规则(我认为应该这样),那么您应该能够将这些命名空间声明放在这些用户控件的任何包含元素上(例如,找到两者最近的共同祖先)。这样以后就没有必要明确地引用它们了。谢谢你的回答,为了清晰起见,我编辑了这个问题。我看不出我会如何让你的回答起作用——也许我的问题不清楚。你能说得更详细一点吗?啊,我明白了。因此,在代码隐藏部分基本上解决了这个问题。这并不完全是我所希望的,但它确实使重命名依赖项变得容易。