gpt4 book ai didi

c# - 如何在 wpf 中将两个组合框绑定(bind)在一起

转载 作者:行者123 更新时间:2023-12-03 10:59:36 25 4
gpt4 key购买 nike

我有 2 个组合框,一个包含“项目”列表,另一个包含“子项目”列表。

子项列表取决于当前选定的项。

我已经完成了大部分工作(通过将 Subitems 的 ItemSource 绑定(bind)到 PossibleSubitems 属性),但是问题是当我更改 Item 并且 Subitem 不再对新项目有效时。在这种情况下,我只想选择第一个有效的子项,但我得到了一个空白的组合框。请注意,我认为类中的属性设置正确,但绑定(bind)似乎没有正确反射(reflect)它。

这是一些代码,可以向您展示我在做什么。在这种情况下,我有:
'项目 1' 可以有子项目 A 或子项目 B 和
'项目 2' 可以有子项目 B 或子项目 C

当我选择了子项 A 后切换到第 2 项时,问题就出现了。

XAML

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="134" Width="136">
<StackPanel Height="Auto" Width="Auto">
<ComboBox ItemsSource="{Binding PossibleItems, Mode=OneWay}" Text="{Binding CurrentItem}"/>
<ComboBox ItemsSource="{Binding PossibleSubitems, Mode=OneWay}" Text="{Binding CurrentSubitem}"/>
</StackPanel>
</Window>

代码背后:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace WpfApplication1
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
// List of potential Items, used to populate the options for the Items combo box
public ObservableCollection<string> PossibleItems
{
get
{
ObservableCollection<string> retVal = new ObservableCollection<string>();
retVal.Add("Item 1");
retVal.Add("Item 2");
return retVal;
}
}

// List of potential Items, used to populate the options for the Subitems combo box
public ObservableCollection<string> PossibleSubitems
{
get
{
ObservableCollection<string> retVal = new ObservableCollection<string>();
if (CurrentItem == PossibleItems[0])
{
retVal.Add("Subitem A");
retVal.Add("Subitem B");
}
else
{
retVal.Add("Subitem B");
retVal.Add("Subitem C");
}
return retVal;
}
}

// Track the selected Item
private string _currentItem;
public string CurrentItem
{
get { return _currentItem; }
set
{
_currentItem = value;
// Changing the item changes the possible sub items
NotifyPropertyChanged("PossibleSubitems");
}
}

// Track the selected Subitem
private string _currentSubitem;
public string CurrentSubitem
{
get { return _currentSubitem; }
set
{
if (PossibleSubitems.Contains(value))
{
_currentSubitem = value;
}
else
{
_currentSubitem = PossibleSubitems[0];
// We're not using the valuie specified, so notify that we have in fact changed
NotifyPropertyChanged("CurrentSubitem");
}
}
}


public MainWindow()
{
InitializeComponent();

this.DataContext = this;
CurrentItem = PossibleItems[0];
CurrentSubitem = PossibleSubitems[0];
}

public event PropertyChangedEventHandler PropertyChanged;
internal void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

}
}

最佳答案

我重写了我自己的示例 - 保留它的代码,以免偏离您的示例太多。此外,我使用的是 .NET 4.5,因此不必在 OnPropertyChanged 调用中提供属性名称 - 如果在 .NET 4.0 上,则需要插入它们。这适用于所有场景。

在实践中,我建议根据 MVVM 模式将此代码定位在 View 模型中。除了 DataContext 的绑定(bind)之外,它看起来与这个实现并没有太大的不同。

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace WpfApplication1
{
public partial class MainWindow: Window, INotifyPropertyChanged
{
private string _currentItem;
private string _currentSubitem;
private ObservableCollection<string> _possibleItems;
private ObservableCollection<string> _possibleSubitems;

public MainWindow()
{
InitializeComponent();

LoadPossibleItems();
CurrentItem = PossibleItems[0];

UpdatePossibleSubItems();

DataContext = this;
CurrentItem = PossibleItems[0];
CurrentSubitem = PossibleSubitems[0];

PropertyChanged += (s, o) =>
{
if (o.PropertyName != "CurrentItem") return;
UpdatePossibleSubItems();
ValidateCurrentSubItem();
};
}

private void ValidateCurrentSubItem()
{
if (!PossibleSubitems.Contains(CurrentSubitem))
{
CurrentSubitem = PossibleSubitems[0];
}
}

public ObservableCollection<string> PossibleItems
{
get { return _possibleItems; }
private set
{
if (Equals(value, _possibleItems)) return;
_possibleItems = value;
OnPropertyChanged();
}
}

public ObservableCollection<string> PossibleSubitems
{
get { return _possibleSubitems; }
private set
{
if (Equals(value, _possibleSubitems)) return;
_possibleSubitems = value;
OnPropertyChanged();
}
}

public string CurrentItem
{
get { return _currentItem; }
private set
{
if (value == _currentItem) return;
_currentItem = value;
OnPropertyChanged();
}
}

public string CurrentSubitem
{
get { return _currentSubitem; }
set
{
if (value == _currentSubitem) return;
_currentSubitem = value;
OnPropertyChanged();
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void LoadPossibleItems()
{
PossibleItems = new ObservableCollection<string>
{
"Item 1",
"Item 2"
};
}

private void UpdatePossibleSubItems()
{
if (CurrentItem == PossibleItems[0])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem A",
"Subitem B"
};
}

else if (CurrentItem == PossibleItems[1])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem B",
"Subitem C"
};
}
}

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

关于c# - 如何在 wpf 中将两个组合框绑定(bind)在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19974930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com