C# 通过可观察收集<&燃气轮机;类型作为依赖项属性
我正在尝试创建一个多选Combobox自定义控件,这个自定义控件应该公开一个名为DropDownDataSource的依赖属性,通过该属性,控件的用户可以决定绑定到Combobox的日期。我的代码如下所示: MainPage.XamlC# 通过可观察收集<&燃气轮机;类型作为依赖项属性,c#,xaml,uwp,uwp-xaml,C#,Xaml,Uwp,Uwp Xaml,我正在尝试创建一个多选Combobox自定义控件,这个自定义控件应该公开一个名为DropDownDataSource的依赖属性,通过该属性,控件的用户可以决定绑定到Combobox的日期。我的代码如下所示: MainPage.Xaml <Grid> <local:CustomComboBox x:Name="customcb" DropDownDataSource="{x:Bind DropDownDataSource, Mode=OneW
<Grid>
<local:CustomComboBox x:Name="customcb" DropDownDataSource="{x:Bind DropDownDataSource, Mode=OneWay}" Loaded="CustomControl_Loaded"> </local:CustomComboBox>
</Grid>
MainPage.Xaml.cs
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
private ObservableCollection<Item> _dropDownDataSource;
public ObservableCollection<Item> DropDownDataSource
{
get => _dropDownDataSource;
set
{
_dropDownDataSource = value;
OnPropertyChanged();
}
}
public MainPage()
{
this.InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void CustomControl_Loaded(object sender, RoutedEventArgs e)
{
var Items = new ObservableCollection<Item>(Enumerable.Range(1, 10)
.Select(x => new Item
{
Text = string.Format("Item {0}", x),
IsChecked = x == 40 ? true : false
}));
DropDownDataSource = Items;
}
}
公共密封部分类主页面:第页,INotifyPropertyChanged
{
私有ObservableCollection\u dropDownDataSource;
公共ObservableCollection下拉数据源
{
get=>\u dropDownDataSource;
设置
{
_dropDownDataSource=值;
OnPropertyChanged();
}
}
公共主页()
{
this.InitializeComponent();
}
公共事件属性更改事件处理程序属性更改;
public void OnPropertyChanged([CallerMemberName]string name=”“)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
已加载私有void CustomControl_(对象发送方,路由目标)
{
var项目=新的ObservableCollection(可枚举范围(1,10)
.选择(x=>新项目
{
Text=string.Format(“项{0}”,x),
IsChecked=x==40?真:假
}));
DropDownDataSource=项目;
}
}
模型
public class Item : BindableBase
{
public string Text { get; set; }
bool _IsChecked = default;
public bool IsChecked { get { return _IsChecked; } set { SetProperty(ref _IsChecked, value); } }
}
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T storage, T value,
[System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
{
if (!object.Equals(storage, value))
{
storage = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
公共类项:BindableBase
{
公共字符串文本{get;set;}
bool\u IsChecked=默认值;
public bool IsChecked{get{return{u IsChecked;}set{SetProperty(ref{u IsChecked,value);}
}
公共抽象类BindableBase:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的无效设置属性(参考T存储、T值、,
[System.Runtime.CompilerServices.CallerMemberName]字符串propertyName=null)
{
如果(!object.Equals(存储,值))
{
储存=价值;
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
受保护的void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName]字符串propertyName=null)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
CustomUserControl XAML
<Grid x:Name="GrdMainContainer">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox Width="200" FontSize="24" Text="{Binding Header, Mode=TwoWay}"
IsReadOnly="True" TextWrapping="Wrap" MaxHeight="200" />
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="200" Width="200" Background="White">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Text}"
FontSize="24"
Foreground="Black"
IsChecked="{Binding IsChecked, Mode=TwoWay}"
IsThreeState="False" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Grid>
CustomUserControl Cs文件
public sealed partial class CustomComboBox : UserControl
{
public CustomComboBox()
{
this.InitializeComponent();
}
public ObservableCollection<Item> DropDownDataSource
{
get { return (ObservableCollection<Item>)GetValue(DropDownDataSourceProperty); }
set { SetValue(DropDownDataSourceProperty, value); }
}
public static readonly DependencyProperty DropDownDataSourceProperty =
DependencyProperty.Register("DropDownDataSource", typeof(ObservableCollection<Item>), typeof(CustomComboBox), new PropertyMetadata("", HasDropDownItemUpdated));
private static void HasDropDownItemUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is CustomComboBox ucrcntrl)
{
var grd = UIElementExtensions.FindControl<Grid>(ucrcntrl, "GrdMainContainer");
grd.DataContext = ucrcntrl.DropDownDataSource as ObservableCollection<Item>;
}
}
}
公共密封部分类CustomComboBox:UserControl
{
公共CustomComboBox()
{
this.InitializeComponent();
}
公共ObservableCollection下拉数据源
{
get{return(ObservableCollection)GetValue(DropDownDataSourceProperty);}
set{SetValue(DropDownDataSourceProperty,value);}
}
公共静态只读从属属性DropDownDataSourceProperty=
DependencyProperty.Register(“DropDownDataSource”、typeof(ObservableCollection)、typeof(CustomComboBox)、new PropertyMetadata(“HasDropDownItemUpdated”);
私有静态void HasDropDownItemUpdated(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
如果(d是自定义组合框ucrcntrl)
{
var grd=UIElementExtensions.FindControl(ucrcntrl,“GrdMainContainer”);
grd.DataContext=ucrcntrl.DropDownDataSource作为ObservableCollection;
}
}
}
在我看来一切都很好,但出于某种原因,下拉列表是空的。如果我将视图模型直接指定给控件,而不是dependency属性,则效果很好。但在我的情况下,我必须在用户控件上为最终用户使用诸如DataSource、SelectedIndex等属性。有人能指出这里出了什么问题吗?
,我已附上完整代码的副本。我下载了您的示例代码,问题应该在绑定中
不建议使用这种书写方式。在可观测集合
中,项
是受保护的属性,不适合作为绑定属性
您可以尝试直接在ItemsControl
中绑定依赖项属性:
此外,您可能已经注意到,我修改了复选框
的样式,并将内容重写为文本块
,因为在复选框
的默认样式中,前台
不绑定到内部的ContentPresenter
谢谢。file.io URL似乎不正确。为什么要使用自定义组合框扩展用户控件?您能不能简单地扩展现有的组合框类并使用标准的itemssource?或者,如果只需要更改控件模板的方式,只需创建一个新的控件模板looks@RandRandom@the.Doc我正在尝试创建一个多选组合框,它在UWP中不可用