使用MonoDevelop和Gtk3在gtk#中定制组合框控件

目标 通过共享这个示例,鼓励其他程序员使用Mono / MonoDevelop / Gtk#组合。使它作为一个基本的Gtk小部件使用起来简单,同时增加尽可能少的开销。通过隐藏特定于gtk的实现细节,使Windows / Forms / WPF程序员更容易访问它。 学分 感谢Mono和MonoDevelop团队使在Linux上运行c#程序成为可能。还要感谢gtk#团队提供的框架。 背景 我正在将我的Windows c# WPF / MVVM应用程序移植到Linux / Mono / Gtk3。我一边学习Gtk工具包,一边努力编写工具,以便尽可能多地使用现有代码。组合框在任何地方都被使用,所以这是我处理的第一个项目

  

 

。 概念 首先,我想说的是,我非常怀念WPF绑定带来的便利。 它们使得将任何类型的类列表连接到一个组合框变得很简单。你设置了ItemsSource, DisplayMemberPath, SelectedValuePath和SelectedValue属性,WPF就会为你发挥它的魔力。 在这里,我们必须自己做,所以我们必须做的越少越好。因此,引用著名的飞机设计师Ed Heinemann[1]的话,我们必须“简化并增加轻盈度”。 如果你把ComboBox的函数简化为最简单的形式,你会得到这样的结论,本质上,它要做它的工作,它只需要: 一个能够跟踪每一项的整数“键”或索引,以及一个作为该项的描述显示的关联字符串。 因此,如果我们要创建一个具有int键和字符串描述的小类,例如: 隐藏,复制Code

public class ComboItem
{
   public int Key { get; set; }
   public String Description { get; set; }
 }

给ComboBox提供一个列表,它应该可以正常工作。事实证明,我们甚至不需要这样做,因为c#非常方便地为我们提供了KeyValuePair类。这里是HComboBox控件,它操作一系列的keyvaluepairstringgt;这是你能得到的最简单和通用的东西。 解决方案 HComboBox控件派生自HBox,并包含一个ComboBoxText,因此得名。 属性 获取/设置高度/宽度获取ComboBoxText成员,以便它可以被客户端直接操作,如果需要的话。 方法 隐藏,复制co全无加载项目(Ilist<KeyValuePair<int,String>>lst) 将项目列表加载到组合框中。WPF使用ItemsSource,但是它可以很好地完成同样的工作,同时还隐藏了特定于gtk的代码。 隐藏,CodeKeyValuePair<复印件;int, String>GetSelection () 和: 隐藏,复制co全无SetSelection(int nKey) 都是不言而喻的。它们也可以对用户“隐藏”特定于gtk的详细信息。 事件 它公开已更改的事件,客户端可以使用该事件来知道所选项何时发生更改。 示例使用 有关如何使用此控件,请参阅所附示例程序的MainWindow类。 为了演示如何对keyvaluepair&int,String>进行打包/解包,让我们定义一个简单的类作为我们的域对象: 隐藏,复制Code

public class DayOfWeek
{
  public int Day { get; set; }
  public String Name { get; set; }
}

让我们假设客户有一个列表: 隐藏,复制Code

IList<DayOfWeek> lst = new List<DayOfWeek>()
{
  new DayOfWeek() { Day = 0, Name = "" },
  new DayOfWeek() { Day = 1, Name = "Sunday" },
  new DayOfWeek() { Day = 2, Name = "Monday" },
  new DayOfWeek() { Day = 3, Name = "Tuesday" },
  new DayOfWeek() { Day = 4, Name = "Wednesday" },
  new DayOfWeek() { Day = 5, Name = "Thursday" },
  new DayOfWeek() { Day = 6, Name = "Friday" },
  new DayOfWeek() { Day = 7, Name = "Saturday" },
};

然后我们需要一个函数来将上面的列表转换为KeyValuePairs列表,我们可以将其传递给组合框。 在我们的例子中,它看起来像这样(为便于阅读而展开): 隐藏,复制Code

private IList<KeyValuePair<int,String>> ConvertToComboList(IList<DayOfWeek>lst)
{
IList<KeyValuePair<int,String>> lstRet= new List<KeyValuePair<int,String>>();

    if( lst != null && lst.Count > 0 )
    {
        foreach( DayOfWeek dow in lst )
        {
            lstRet.Add( new KeyValuePair<int, string>( dow.Day, dow.Name ) );
        }
    }
    return lstRet;
} 

最后,我们可以将列表加载到组合框中: 隐藏,复制Code

m_hcbx.LoadItems( ConvertToComboList( lst ) );

一旦组合框被初始化,我们可以这样设置选择: 隐藏,复制Code

// Example usage :
// Set selected value to today
DateTime dt = DateTime.Now;

m_hcbx.SetSelection( (( int )dt.DayOfWeek ) + 1 );  // Sunday is 0, so +1

和检索当前选择的项目: 隐藏,复制Code

KeyValuePair<int,String> day = m_hcbx.GetSelection();

// use day.Key and day.Value here...

这就是它的全部。 讲话 这种方法的缺点是,对于希望在HComboBox中显示的每个遗留类,都需要编写专用的ConvertToComboList()函数。 在遗留代码可用并能够被修改/增强的情况下,就像我的情况一样,一个解决方案是定义一个类似这样的接口: 隐藏,复制Code

public interface IListable
{
    int Key { get; }
    String Description { get; }
} 

并让遗留类实现它。 然后只需要一个模板化的ConvertToComboList()函数,因此: 隐藏,复制CodeIList< KeyValuePair< int, String>比;ConvertComboList< T> (IList< T>1) where T: IListable 它将与实现IListable接口的所有类一起工作。根据我的经验,出现在组合框中的类已经有一个可以用作键的integer属性和一个可以用作描述的String属性,因此接口的实现很简单。 给读者的练习 此控件派生自HBox并包含一个ComboBoxText。另一种方法是直接从ComboBoxText派生并使用添加的功能对其进行扩展。就这样,我采取了懦夫的方式,通过getter道具暴露了ComboBoxText成员erty。 需求 monodevelop(当前版本7.8.4)gtk3库(当前版本3.22.25.56) 提供的示例应用程序是MonoDevelop解决方案。它需要Gtk 3包。 因为这些是dll,所以它们不包含在示例项目中,而是包含在包中。包含配置文件。在MonoDevelop中打开解决方案后,选择恢复/更新包,NuGet将获取它们。 历史 2020年3月25日:初版 本文转载于:http://www.diyabc.com/frontweb/news180.html

posted @ 2020-08-04 02:51  Dincat  阅读(413)  评论(0编辑  收藏  举报