![](/img/trans.png)
[英]How to Bind ItemsSource with ObservableCollection in WPF
[英]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}"/>
我已經看到了很多使用FindAncestor
的RealtiveSource
答案,但是對我來說不是。 我在這里想念什么?
您需要將您的屬性更改為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.