gpt4 book ai didi

silverlight - UserControl 公开多个内容属性!那将是多么令人兴奋!

转载 作者:行者123 更新时间:2023-12-04 02:51:29 31 4
gpt4 key购买 nike

我正在尝试创建一个有望公开多个内容属性的 UserControl。然而,我却被失败所困扰!

我的想法是创建一个公开两个内容属性的优秀用户控件(我们称之为 MultiContent),以便我可以执行以下操作:

    <local:MultiContent>
<local:MultiContent.ListContent>
<ListBox x:Name="lstListOfStuff" Width="50" Height="50" />
</local:MultiContent.ListContent>
<local:MultiContent.ItemContent>
<TextBox x:Name="txtItemName" Width="50" />
</local:MultiContent.ItemContent>
</local:MultiContent>

这将非常有用,现在我可以根据情况更改 ListContent 和 ItemContent,将常用功能分解到 MultiContent 用户控件中。

但是,按照我目前的实现方式,我无法访问 MultiContent 控件的这些内容属性内的 UI 元素。例如,lstListOfStufftxtItemName 在我尝试访问它们时都是 null:

public MainPage() {
InitializeComponent();
this.txtItemName.Text = "Item 1"; // <-- txtItemName is null, so this throws an exception
}

下面是我如何实现 MultiContent 用户控件:

XAML:多内容.xaml

<UserControl x:Class="Example.MultiContent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<ContentControl x:Name="pnlList" Grid.Column="0" />
<ContentControl x:Name="pnlItem" Grid.Column="1" />
</Grid>
</UserControl>

代码隐藏:MultiContent.xaml.cs

// Namespaces Removed
namespace Example
{
public partial class MultiContent : UserControl
{
public UIElement ListContent
{
get { return (UIElement)GetValue(ListContentProperty); }
set
{
this.pnlList.Content = value;
SetValue(ListContentProperty, value);
}
}
public static readonly DependencyProperty ListContentProperty =
DependencyProperty.Register("ListContent", typeof(UIElement), typeof(MultiContent), new PropertyMetadata(null));

public UIElement ItemContent
{
get { return (UIElement)GetValue(ItemContentProperty); }
set
{
this.pnlItem.Content = value;
SetValue(ItemContentProperty, value);
}
}
public static readonly DependencyProperty ItemContentProperty =
DependencyProperty.Register("ItemContent", typeof(UIElement), typeof(MultiContent), new PropertyMetadata(null));


public MultiContent()
{
InitializeComponent();
}
}
}

我可能完全错误地实现了这个。有谁知道我怎样才能让它正常工作?如何从父控件按名称访问这些 UI 元素?关于如何更好地做到这一点的任何建议?谢谢!

最佳答案

你当然可以实现你的目标,但你需要采取不同的方法。

在您的解决方案中,您试图为 UIElement 设置一个依赖属性 - 由于它永远不会被设置并且默认值为 null,这就是您获得 NullReference 异常的原因。您可能会继续将默认值从 null 更改为 new TextBox 或类似的东西,但即使它确实有效,它仍然感觉像是 hack。

在 Silverlight 中,您必须自己实现依赖属性。但是您没有按应有的方式实现它们 - 我倾向于使用此 dependency property generator这样做。

DP 的一大优点是它们支持更改通知。因此,考虑到这一点,让您的示例工作所需要做的就是为 DP 定义:ItemContent 和 ListContent,其类型与 Content(对象)相同,当框架通知您其中任何一个已更改时,只需更新您的文本框!所以这是执行此操作的代码:

多内容.xaml:

   <Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<ContentControl x:Name="pnlList" Grid.Column="0" />
<ContentControl x:Name="pnlItem" Grid.Column="1" />
</Grid>

MultiContent.xaml.cs:

namespace MultiContent
{
public partial class MultiContent : UserControl
{
#region ListContent

/// <summary>
/// ListContent Dependency Property
/// </summary>
public object ListContent
{
get { return (object)GetValue(ListContentProperty); }
set { SetValue(ListContentProperty, value); }
}
/// <summary>
/// Identifies the ListContent Dependency Property.
/// </summary>
public static readonly DependencyProperty ListContentProperty =
DependencyProperty.Register("ListContent", typeof(object),
typeof(MultiContent), new PropertyMetadata(null, OnListContentPropertyChanged));

private static void OnListContentPropertyChanged
(object sender, DependencyPropertyChangedEventArgs e)
{
MultiContent m = sender as MultiContent;
m.OnPropertyChanged("ListContent");
}

#endregion

#region ItemContent

/// <summary>
/// ItemContent Dependency Property
/// </summary>
public object ItemContent
{
get { return (object)GetValue(ItemContentProperty); }
set { SetValue(ItemContentProperty, value); }
}
/// <summary>
/// Identifies the ItemContent Dependency Property.
/// </summary>
public static readonly DependencyProperty ItemContentProperty =
DependencyProperty.Register("ItemContent", typeof(object),
typeof(MultiContent), new PropertyMetadata(null, OnItemContentPropertyChanged));

private static void OnItemContentPropertyChanged
(object sender, DependencyPropertyChangedEventArgs e)
{
MultiContent m = sender as MultiContent;
m.OnPropertyChanged("ItemContent");
}

#endregion

/// <summary>
/// Event called when any chart property changes
/// Note that this property is not used in the example but is good to have if you plan to extend the class!
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Called to invoke the property changed event
/// </summary>
/// <param name="propertyName">The property that has changed</param>
protected void OnPropertyChanged(string propertyName)
{
if (propertyName == "ListContent")
{
// The ListContent property has been changed, let's update the control!
this.pnlList.Content = this.ListContent;
}
if (propertyName == "ItemContent")
{
// The ListContent property has been changed, let's update the control!
this.pnlItem.Content = this.ItemContent;
}
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public MultiContent()
{
InitializeComponent();
}
}
}

主页.xaml:

    <Grid x:Name="LayoutRoot" Background="White">
<local:MultiContent>
<local:MultiContent.ListContent>
<ListBox x:Name="lstListOfStuff" Width="50" Height="50" />
</local:MultiContent.ListContent>
<local:MultiContent.ItemContent>
<TextBox x:Name="txtItemName" Width="50" />
</local:MultiContent.ItemContent>
</local:MultiContent>
</Grid>

这应该可以解决问题!

关于silverlight - UserControl 公开多个内容属性!那将是多么令人兴奋!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2068125/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com