gpt4 book ai didi

wpf - 需要基于第二个 ComboBox 的 SelectedValue 设置 WPF MVVM ComboBox ItemsSource 的简单工作示例

转载 作者:行者123 更新时间:2023-12-04 17:35:01 26 4
gpt4 key购买 nike

任何人都可以向我展示一个 WPF MVVM 应用程序的简单工作示例,以根据 ComboBox A 的 SelectedItem 设置组合框 B 的 ItemsSource 吗?

从我在这个网站上的发现看来,它变得太复杂太快了。

完成它的“正确” MVVM 方法是什么?

谢谢你。

编辑
我使用 Didier 的示例进行了更新。
我的 XAML 的摘录:

<ComboBox Name="BrowserStackDesktopOS" ItemsSource="Binding Platforms.AvailableBrowserStackDesktopOSes}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopOSSelectedValue, Mode=TwoWay}"/>

<ComboBox Name="BrowserStackDesktopOSVersion" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopOSVersions}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopOSVersionSelectedValue, Mode=TwoWay}"/>

<ComboBox Name="BrowserStackDesktopBrowser" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopBrowsers}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopBrowserSelectedValue, Mode=TwoWay}"/>

<ComboBox Name="BrowserStackDesktopBrowserVersion" ItemsSource="{Binding Platforms.AvailableBrowserStackDesktopBrowserVersions}" SelectedIndex="0" SelectedItem="{Binding Platforms.BrowserStackDesktopBrowserVersionSelectedValue, Mode=TwoWay}"/>

还有一个我的代码示例:
public string BrowserStackDesktopOSSelectedValue {
get { return (string)GetValue(BrowserStackDesktopOSSelectedValueProperty); }
set { SetValue(BrowserStackDesktopOSSelectedValueProperty, value);
AvailableBrowserStackDesktopOSVersions = AvailableBrowserStackDesktopPlatforms.GetOSVersions(BrowserStackDesktopOSSelectedValue);
NotifyPropertyChanged("BrowserStackDesktopOSSelectedValue");
}
}

但是,当我为第一个 ComboBox 选择一个值时,什么也没有发生。我想要填充下一个 ComboBox 的 Itemsource。

我做错了什么?

最佳答案

基本上,您需要在 MVVM 2 中公开组合框选项的值集合和选定值的两个属性。

一开始只有第一个集合如果填充了值。当第一个选定的值更改时,第二个集合将填充适当的值。这是一个示例实现:

后面的代码:

public partial class MainWindow : Window
{

public MainWindow()
{
InitializeComponent();

//Set the data context of the window
DataContext = new TestVM();
}
}


public class TestVM : INotifyPropertyChanged
{

#region Class attributes

protected static string[] firstComboValues = new string[] { "Choice_1", "Choice_2" };

protected static string[][] secondComboValues =
new string[][] {
new string[] { "value_1_1", "value_1_2", "value_1_3" },
new string[] { "value_2_1", "value_2_2", "value_2_3" }
};


#endregion

#region Public Properties

#region FirstSelectedValue

protected string m_FirstSelectedValue;

/// <summary>
///
/// </summary>
public string FirstSelectedValue
{
get { return m_FirstSelectedValue; }
set
{
if (m_FirstSelectedValue != value)
{
m_FirstSelectedValue = value;
UpdateSecondComboValues();
NotifyPropertyChanged("FirstSelectedValue");
}
}
}

#endregion

#region SecondSelectedValue

protected string m_SecondSelectedValue;

/// <summary>
///
/// </summary>
public string SecondSelectedValue
{
get { return m_SecondSelectedValue; }
set
{
if (m_SecondSelectedValue != value)
{
m_SecondSelectedValue = value;
NotifyPropertyChanged("SecondSelectedValue");
}
}
}

#endregion

#region FirstComboValues

protected ObservableCollection<string> m_FirstComboValues;

/// <summary>
///
/// </summary>
public ObservableCollection<string> FirstComboValues
{
get { return m_FirstComboValues; }
set
{
if (m_FirstComboValues != value)
{
m_FirstComboValues = value;
NotifyPropertyChanged("FirstComboValues");
}
}
}

#endregion

#region SecondComboValues

protected ObservableCollection<string> m_SecondComboValues;

/// <summary>
///
/// </summary>
public ObservableCollection<string> SecondComboValues
{
get { return m_SecondComboValues; }
set
{
if (m_SecondComboValues != value)
{
m_SecondComboValues = value;
NotifyPropertyChanged("SecondComboValues");
}
}
}

#endregion

#endregion

public TestVM()
{
FirstComboValues = new ObservableCollection<string>(firstComboValues);
}

/// <summary>
/// Update the collection of values for the second combo box
/// </summary>
protected void UpdateSecondComboValues()
{
int firstComboChoice;
for (firstComboChoice = 0; firstComboChoice < firstComboValues.Length; firstComboChoice++)
{
if (firstComboValues[firstComboChoice] == FirstSelectedValue)
break;
}


if (firstComboChoice == firstComboValues.Length)// just in case of a bug
SecondComboValues = null;
else
SecondComboValues = new ObservableCollection<string>(secondComboValues[firstComboChoice]);

}


#region INotifyPropertyChanged implementation

public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

#endregion
}

以及相关的 XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="window" x:Class="Testing1.MainWindow">

<Grid>

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width=" 300">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="10"/>
<RowDefinition/>
</Grid.RowDefinitions>

<ComboBox x:Name="FirstOne" ItemsSource="{Binding FirstComboValues}" SelectedItem="{Binding FirstSelectedValue, Mode=TwoWay}"/>

<ComboBox x:Name="SecondOne" ItemsSource="{Binding SecondComboValues}" SelectedItem="{Binding SecondSelectedValue, Mode=TwoWay}" Grid.Row="2"/>

</Grid>

</Grid>

</Window>

如您所见 SelectedValue组合框的属性以双向模式绑定(bind),所以当 SelectedValue组合框的属性更改它会更改 VM 端的值。在 FirstSelectedValue属性 setter UpdateSecondComboValues()调用方法来更新第二个组合框的值。

编辑:

发生这种情况是因为您混合了 INotifPropertyChanged 和 DependencyObject。你应该选择其中之一。通常你在你的虚拟机中实现 INotifyPropertyChanged 并且属性 setter 中的代码将起作用。

但是,如果您从 DependencyObject 继承,则不应在 setter/getter 中编写任何代码。 TwoWay 绑定(bind)永远不会调用它。它只会在内部调用 GetValue(...) 。为了能够对 DependencyProperty 更改执行操作,您应该使用属性更改处理程序以不同方式声明它:
#region BrowserStackDesktopOSSelectedValue 

/// <summary>
/// BrowserStackDesktopOSSelectedValue Dependency Property
/// </summary>
public static readonly DependencyProperty BrowserStackDesktopOSSelectedValue Property =
DependencyProperty.Register("BrowserStackDesktopOSSelectedValue ", typeof(string), typeof(YourVM),
new FrameworkPropertyMetadata((string)null,
new PropertyChangedCallback(OnBrowserStackDesktopOSSelectedValue Changed)));

/// <summary>
/// Gets or sets the BrowserStackDesktopOSSelectedValue property. This dependency property
/// indicates ....
/// </summary>
public string BrowserStackDesktopOSSelectedValue
{
get { return (string)GetValue(BrowserStackDesktopOSSelectedValue Property); }
set { SetValue(BrowserStackDesktopOSSelectedValue Property, value); }
}

/// <summary>
/// Handles changes to the BrowserStackDesktopOSSelectedValue property.
/// </summary>
private static void OnBrowserStackDesktopOSSelectedValue Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
YourVM target = (YourVM)d;
string oldBrowserStackDesktopOSSelectedValue = (string)e.OldValue;
string newBrowserStackDesktopOSSelectedValue = target.BrowserStackDesktopOSSelectedValue ;
target.OnBrowserStackDesktopOSSelectedValue Changed(oldBrowserStackDesktopOSSelectedValue , newBrowserStackDesktopOSSelectedValue );
}

/// <summary>
/// Provides derived classes an opportunity to handle changes to the BrowserStackDesktopOSSelectedValue property.
/// </summary>
protected virtual void OnBrowserStackDesktopOSSelectedValue Changed(string oldBrowserStackDesktopOSSelectedValue , string newBrowserStackDesktopOSSelectedValue )
{
//Here write some code to update your second ComboBox content.
AvailableBrowserStackDesktopOSVersions = AvailableBrowserStackDesktopPlatforms.GetOSVersions(BrowserStackDesktopOSSelectedValue);
}

#endregion

顺便说一句,我总是使用 Dr WPF snippets编写 DP,因此它运行得更快。

关于wpf - 需要基于第二个 ComboBox 的 SelectedValue 设置 WPF MVVM ComboBox ItemsSource 的简单工作示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23168068/

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