C# 通过可观察收集<&燃气轮机;类型作为依赖项属性

C# 通过可观察收集<&燃气轮机;类型作为依赖项属性,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

我正在尝试创建一个多选Combobox自定义控件,这个自定义控件应该公开一个名为DropDownDataSource的依赖属性,通过该属性,控件的用户可以决定绑定到Combobox的日期。我的代码如下所示:

MainPage.Xaml

<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中不可用