我的問題基本上是this one。儘管如此,我認爲這將有助於提供更多的信息和代碼,使其更容易重現問題。如何綁定RibbonComboBox SelectedItem
使用來自RibbonControlsLibrary的Microsoft.Windows.Controls.Ribbon.RibbonComboBox感覺就像是漫步在一個充滿bug的大沼澤中,而不是你如果知道解決方法的話。
Anywho。我遇到的最大問題是數據綁定我的SelectedItem。
以下是我開始使用(在我找到約RibbonGallery?)。要在ComboBox的子元素上使用ItemsSource和SelectedItem,即使在同一級上也已經給了我heebie-jeebies,但這似乎是正確的。
在示例應用程序中,我將ViewItem設置爲ViewModel的構造函數中。但是,運行應用程序時,不會顯示SelectedItem。即使VS設計師正確地顯示「第二選擇」!
運行的應用程序: VS設計師:
在調試的SelectedItem二傳手,你會發現多遍。在第一次在ctor中設置「第二個選項」(1,見下面的調試日誌)後,它將重置爲空(2)(通過外部代碼,我認爲控制本身)。當在UI中打開下拉菜單時,它將再次設置爲空(3),然後在選擇一個值時,將該值設爲兩倍(4,5)。我選擇了「第二選項」,然後用「第一選項」(6-9)重複該過程。這產生了以下日誌(忽略從色帶控制......在1001個綁定例外):
的一個大問題是明顯(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>
視圖模型:
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"); } }
}
}
你救了我的大量時間...非常感謝 !!! – 2016-08-26 20:09:59