[WPF]自定义控件中如果想要自定义集合属性该怎么办?

weixin_38054676 2018-01-09 06:51:49
自己继承Window写了一个自定义的窗口,然后想要管理窗口最上方的菜单栏,这样就需要一个集合来存储菜单项。之前仅仅接触过类似Menu此类的控件,它们继承了ItemsControl,拥有Items属性,所以我也想要自定义一个类似Items的属性,但是不知道该怎么初始化它。有没有人做过类似的功能,求指教!还请告诉我如何在模版中绑定此元素,谢谢!
public ItemCollection TopBarMenuItem
{
get { return (ItemCollection)GetValue(TopBarMenuItemProperty); }
set { SetValue(TopBarMenuItemProperty, value); }
}

public static readonly DependencyProperty TopBarMenuItemProperty =
DependencyProperty.Register(nameof(TopBarMenuItem), typeof(ItemCollection), _ownerType);

...全文
217 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38108918 2018-01-10
  • 打赏
  • 举报
回复
Thanks!
很详细,终于了却了我一个心结!
weixin_38086192 2018-01-10
  • 打赏
  • 举报
回复
https://stackoverflow.com/questions/12528286/binding-to-user-controls-collection-property-items-in-xaml







The problem here is, that the Binding to ElementName=tb1 can not be resolved, even it will never be evaluated. A Binding to an ElementName is resolved for DependencyObjects which are in the visual or logical Tree of a WPF Application. Adding items to your
ObservableCollection (MyList) only means adding the items to the Collection, but not into the Visual Tree.

Edit: Here is the approach discussed in the comments:
In your Window/Page:
<Window.Resources> <!-- Declare the ViewModel as Resource --> <my:ViewModel x:Key="viewModel"> <my:ViewModel.MyList> <my:Test A="Hello sweet" /> <my:Test A="ViewModel" /> </my:ViewModel.MyList> </my:ViewModel> </Window.Resources> <!-- Assign Ressource as DataContext --> <StackPanel DataContext="{StaticResource viewModel}"> <TextBox x:Name="tb1" Text="def"/> <!-- Reference your list within the ViewModel --> <ListBox ItemsSource="{Binding Path=MyList}"> <ListBox.ItemTemplate> <DataTemplate> <!-- Bind your property --> <TextBlock Text="{Binding Path=A}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel>
And the implementation of ViewModel:
public class ViewModel { public ViewModel() { this.MyList = new ObservableCollection<Test>(); } public ObservableCollection<Test> MyList { get; set; } }
Of course, class Test no longer needs to implement a DependencyObject. Simple get/set Properties are okay.






专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms
weixin_38106593 2018-01-10
  • 打赏
  • 举报
回复
https://stackoverflow.com/questions/12528286/binding-to-user-controls-collection-property-items-in-xaml







The problem here is, that the Binding to ElementName=tb1 can not be resolved, even it will never be evaluated. A Binding to an ElementName is resolved for DependencyObjects which are in the visual or logical Tree of a WPF Application. Adding items to your
ObservableCollection (MyList) only means adding the items to the Collection, but not into the Visual Tree.

Edit: Here is the approach discussed in the comments:
In your Window/Page:
<Window.Resources> <!-- Declare the ViewModel as Resource --> <my:ViewModel x:Key="viewModel"> <my:ViewModel.MyList> <my:Test A="Hello sweet" /> <my:Test A="ViewModel" /> </my:ViewModel.MyList> </my:ViewModel> </Window.Resources> <!-- Assign Ressource as DataContext --> <StackPanel DataContext="{StaticResource viewModel}"> <TextBox x:Name="tb1" Text="def"/> <!-- Reference your list within the ViewModel --> <ListBox ItemsSource="{Binding Path=MyList}"> <ListBox.ItemTemplate> <DataTemplate> <!-- Bind your property --> <TextBlock Text="{Binding Path=A}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel>
And the implementation of ViewModel:
public class ViewModel { public ViewModel() { this.MyList = new ObservableCollection<Test>(); } public ObservableCollection<Test> MyList { get; set; } }
Of course, class Test no longer needs to implement a DependencyObject. Simple get/set Properties are okay.






专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms
weixin_38089806 2018-01-10
  • 打赏
  • 举报
回复
参考例子
https://stackoverflow.com/questions/7321710/wpf-binding-collection-property-in-usercontrol

You would have to expose two separate properties, much like an ItemsControl which has an

Items and
ItemsSource property. It looks like you want to be able to add items using a binding
and explicitly by adding to your collection. This behavior would differ from an ItemsControl, which only allows you to use the Items or ItemsSource property, but not both at the same time.
There is nothing preventing you from adding support for both ways of specifying items though, but it would be more work on your part.
First, you'd need a DependencyProperty, such as IEnumerable QuestionsSource, which you could bind to:
public readonly static DependencyProperty QuestionsSourceProperty = DependencyProperty.Register("QuestionsSource", typeof(IEnumerable), typeof(FormQuestionReportViewer), new PropertyMetadata(null)); public IEnumerable QuestionsSource { get { return GetValue(QuestionsSourceProperty) as IEnumerable; } set { SetValue(QuestionsSourceProperty, value); } }
second, you would need a regular CLR property, such as ObservableCollection<Question> Questions, which you could add items to explicitly:
private ObservableCollection<Question> questions = new ObservableCollection<Question>(); public ObservableCollection<Question> Questions { get { return questions; } }
Then you could use these properties like so:
<custom:CustomControl QuestionsSource="{Binding Path=Questions}"> <custom:CustomControl.Questions> <custom:Question FullName="{binding Name}" ShortName="{binding ShortName}" RecOrder="{binding RecOrder}" Answer={binding Answer}" /> </custom:CustomControl.Questions> </custom:CustomControl>
The extra work comes when you want to get the full list of items. You'd need to union the two collections into a single collection. This unified collection would be exposed as a third property, which returns a read-only collection.

专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms
weixin_38075050 2018-01-10
  • 打赏
  • 举报
回复
参考例子
https://stackoverflow.com/questions/7321710/wpf-binding-collection-property-in-usercontrol

You would have to expose two separate properties, much like an ItemsControl which has an

Items and
ItemsSource property. It looks like you want to be able to add items using a binding
and explicitly by adding to your collection. This behavior would differ from an ItemsControl, which only allows you to use the Items or ItemsSource property, but not both at the same time.
There is nothing preventing you from adding support for both ways of specifying items though, but it would be more work on your part.
First, you'd need a DependencyProperty, such as IEnumerable QuestionsSource, which you could bind to:
public readonly static DependencyProperty QuestionsSourceProperty = DependencyProperty.Register("QuestionsSource", typeof(IEnumerable), typeof(FormQuestionReportViewer), new PropertyMetadata(null)); public IEnumerable QuestionsSource { get { return GetValue(QuestionsSourceProperty) as IEnumerable; } set { SetValue(QuestionsSourceProperty, value); } }
second, you would need a regular CLR property, such as ObservableCollection<Question> Questions, which you could add items to explicitly:
private ObservableCollection<Question> questions = new ObservableCollection<Question>(); public ObservableCollection<Question> Questions { get { return questions; } }
Then you could use these properties like so:
<custom:CustomControl QuestionsSource="{Binding Path=Questions}"> <custom:CustomControl.Questions> <custom:Question FullName="{binding Name}" ShortName="{binding ShortName}" RecOrder="{binding RecOrder}" Answer={binding Answer}" /> </custom:CustomControl.Questions> </custom:CustomControl>
The extra work comes when you want to get the full list of items. You'd need to union the two collections into a single collection. This unified collection would be exposed as a third property, which returns a read-only collection.

专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

473

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧