gpt4 book ai didi

wpf - 如何对 Ribbons ComboBox 的 SelectedItem 进行数据绑定(bind)

转载 作者:行者123 更新时间:2023-12-01 16:46:54 24 4
gpt4 key购买 nike

我的问题基本上是this one 。不过,我认为提供更多信息和代码将有助于更轻松地重现问题。

使用 RibbonControlsLibrary 中的 Microsoft.Windows.Controls.Ribbon.RibbonComboBox感觉就像走过一个充满 bug 的大沼泽,如果你知道解决办法的话就不会这么做。

任何人。我遇到的最大问题是数据绑定(bind)我的 SelectedItem。

以下是我开始的内容(在我发现 RibbonGallery 之后?)。将 ItemsSource 和 SelectedItem 放在 ComboBox 的子元素上,甚至不在同一级别上,已经让我感到紧张,但这似乎是正确的。

在示例应用程序中,我在 ViewModel 的构造函数中设置 SelectedItem。但是,运行应用程序时,不会显示 SelectedItem。甚至 VS 设计器也正确显示了“第二个选项”!

正在运行的应用程序:Running App VS设计师:Visual Studio Designer

调试 SelectedItem setter 时,您会注意到多次传递。第一次将其设置为 ctor 中的“第二个选项”后(1,请参阅下面的调试日志),它将重置为 null (2)(通过外部代码,我认为是在控件本身中)。当在 UI 中打开下拉列表时,它将再次设置为 null (3),然后在选择一个值时,两次设置为该值 (4,5)。我选择“第二个选项”,然后使用“第一个选项”重复该过程 (6-9)。这生成了以下日志(忽略功能区控件中的一千零一个绑定(bind)异常...):

enter image description here

最大的问题显然是(2),它正在重置我的初始选择。看起来当第一次显示控件时,它被重置。一个非常丑陋的解决方法是通过计时器设置该值。在这个示例应用程序中,在用户控件的 Loaded 事件中设置它确实对我有用,但在我的较重的现实应用程序中,它不起作用。无论如何,这一切都感觉不对劲。有谁知道更好的解决方案吗?

Xaml:

<UserControl x:Class="WpfApplication1.RibbonComboBoxDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:r="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">

<UserControl.DataContext>
<local:ViewModel />
</UserControl.DataContext>

<Grid>
<r:Ribbon >
<r:RibbonTab Header="First Tab">
<r:RibbonGroup Header="Group">
<r:RibbonComboBox >
<r:RibbonGallery SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<r:RibbonGalleryCategory ItemsSource="{Binding Controls}" DisplayMemberPath="Caption" />
</r:RibbonGallery>
</r:RibbonComboBox>
</r:RibbonGroup>
</r:RibbonTab>
<r:RibbonTab Header="Second Tab" />
</r:Ribbon>
</Grid>
</UserControl>

View 模型:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;

namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

public ObservableCollection<ControlBaseModel> Controls { get; private set; }


private ControlBaseModel _selectedItem;
public ControlBaseModel SelectedItem { get { return _selectedItem; } set { LogSelectedItemChange(value); _selectedItem = value; OnPropertyChanged("SelectedItem"); } }

public ViewModel()
{
this.Controls = new ObservableCollection<ControlBaseModel>();

this.Controls.Add(new ControlBaseModel() { Caption = "first option" });
this.Controls.Add(new ControlBaseModel() { Caption = "second option" });

this.SelectedItem = this.Controls[1]; // set to second option
}

int i = 0;
private void LogSelectedItemChange(ControlBaseModel value)
{
i++;
string setObject = "null";
if (value != null)
{
setObject = value.Caption;
}
Debug.WriteLine(string.Format("{0}: SelectedItem.set(): {1}", i, setObject));
}

}

public class ControlBaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

private string _name;
public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } }

private string _caption;
public string Caption { get { return _caption; } set { _caption = value; OnPropertyChanged("Caption"); } }
}
}

最佳答案

虽然 View/UserControl 加载事件是在我的应用程序中 ComboBox SelectedItem 重置为 null 之前发生的,但 ComboBox 加载事件实际上被触发了两次,第二次足够“晚”了。所以我目前的解决方案是这样的:

<r:RibbonComboBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<r:RibbonGallery SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<r:RibbonGalleryCategory ItemsSource="{Binding Controls}" DisplayMemberPath="Caption"/>
</r:RibbonGallery>
</r:RibbonComboBox>

View 模型:

private ControlBaseModel _lastNonNullSelectedItem;

public ObservableCollection<ControlBaseModel> Controls { get; private set; }

private ControlBaseModel _selectedItem;
public ControlBaseModel SelectedItem
{
get { return _selectedItem; }
set
{
if (value != null) { _lastNonNullSelectedItem = value; }
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public ICommand LoadedCommand { get; private set; }


public ViewModel()
{
this.Controls = new ObservableCollection<ControlBaseModel>();
this.LoadedCommand = new ActionCommand(OnLoaded); // ActionCommand: simple implementation of ICommand

this.Controls.Add(new ControlBaseModel() { Caption = "first option" });
this.Controls.Add(new ControlBaseModel() { Caption = "second option" });

this.SelectedItem = this.Controls[1]; // set to second option
}

private void OnLoaded()
{
this.SelectedItem = _lastNonNullSelectedItem;
}

关于wpf - 如何对 Ribbons ComboBox 的 SelectedItem 进行数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15555449/

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