簡體   English   中英

如何將ItemsSource綁定到父窗口的ObservableCollection屬性?

[英]How to bind ItemsSource to ObservableCollection Property of the parent Window?

我知道這已經被問過幾次了,但是到目前為止,所有解決方案都不適合我。 我嘗試將ObservableCollection綁定到組合框的ItemsSource屬性,但失敗了。

ObservalbeCollection是Window.cs的一部分:

public partial class RecordSoundWindow2 : Window
{
    public ObservableCollection<string> RecordingDevices { get; set; }

    public RecordSoundWindow2()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        RecordingDevices = new ObservableCollection<string>();

        for (int n = 0; n < WaveIn.DeviceCount; n++)
        {
            RecordingDevices.Add(WaveIn.GetCapabilities(n).ProductName);
        }
    }

我當然知道它會使用我的麥克風名稱進行更新,但是組合框從不顯示其內容。 到目前為止,我已經嘗試了以下方法:

<ComboBox DockPanel.Dock="Top" Name="cbDevices" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=RecordingDevices}"/>
<ComboBox DockPanel.Dock="Top" Name="cbDevices" ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=RecordingDevices}"/>
<ComboBox DockPanel.Dock="Top" Name="cbDevices" ItemsSource="{Binding Path=RecordingDevices}"/>

我已經看到了很多使用FindAncestorRealtiveSource答案,但是對我來說不是。 我在這里想念什么?

您需要將您的屬性更改為Dependency Property 除非設置DataContext否則綁定將不起作用。

在您的情況下,您是從Window繼承的,因此DependencyProperty是正確的方法。

public ObservableCollection<string> RecordingDevices
    {
        get { return (ObservableCollection<string>)GetValue(RecordingDevicesProperty); }
        set { SetValue(RecordingDevicesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for RecordingDevices.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty RecordingDevicesProperty =
        DependencyProperty.Register("RecordingDevices", typeof(ObservableCollection<string>), typeof(RecordSoundWindow2), new PropertyMetadata(null));

Mike Eason的答案有效。

但是Clemens的INotifyPropertyChanged方法更干凈,我更喜歡它,因此我將其發布為答案。

這是XAML:

<ComboBox Name="cbDevices" Width="200" 
    SelectionChanged="cbDevices_SelectionChanged"
    ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=RecordingDevices}"/>

以下是一個解決方案的代碼,我在另一個答案中找到了一種更好的INotifyPropertyChanged方法,該方法未將屬性名稱指定為字符串,從而可以在以后更好地重命名變量:

public partial class RecordSoundWindow : Window, INotifyPropertyChanged
{
    private IAudioRecorder Recorder;

    public ObservableCollection<string> RecordingDevices { get; set; }

    public RecordSoundWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        InitRecorder();
    }

    private void InitRecorder()
    {
        RecordingDevices = new ObservableCollection<string>();
        Recorder = new AudioRecorder();

        for (int n = 0; n < WaveIn.DeviceCount; n++)
        {
            RecordingDevices.Add(WaveIn.GetCapabilities(n).ProductName);
            OnMyPropertyChanged(() => RecordingDevices);
        }

        //cbDevices.ItemsSource = RecordingDevices;

        if (RecordingDevices.Count > 0)
            cbDevices.SelectedIndex = 0;

        Recorder.SampleAggregator.MaximumCalculated += OnRecorderMaximumCalculated;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    // Raise the event that a property has changed in order to update the visual elements bound to it
    internal void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    //Converts the passed parameter to its name in string
    internal void OnMyPropertyChanged<T>(Expression<Func<T>> memberExpression)
    {
        MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
        OnPropertyChanged(expressionBody.Member.Name);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM