2013-09-21 102 views
0

我需要一个WPF控件,其功能类似于TFS中的“解决冲突”窗口以及其他类似的源代码控制系统。WPF绑定和自定义ListView和ListViewItems

我有以下类

public class Conflict:INotifyPropertyChanged 
{ 
    private string _name; 
    private List<Resolution> _resolutions; 
    private bool _focused; 
    private bool _hasResolutions; 

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

    public List<Resolution> Resolutions 
    { 
     get { return _resolutions; } 
     set 
     { 
      _resolutions = value; 
      OnPropertyChanged("Resolutions"); 
     } 
    } 

    public bool Focused 
    { 
     get { return _focused; } 
     set { 
      _focused = value; 
      OnPropertyChanged("Focused"); 
     } 
    } 

    public bool HasResolutions 

    { 
     get { return _resolutions.Any(); } 
     set 
     { 
      _hasResolutions = value; 
      OnPropertyChanged("HasResolutions"); 
     } 
    } 
} 

public class Resolution 
{ 
    public string Name { get; set; } 

    public void Resolve() 
    { 
     //Logic goes here 
    } 
} 

这几乎等同于团队基础服务器(TFS)的功能性“解决冲突”如下所示窗口:

enter image description here

对于每一行在上面的图像中,它与我的Conflcit对象相同,并且对于每个按钮,它们都是冲突对象上的一个Resolution对象。

我的计划是将我的列表绑定到一个ListView,然后编写一个自定义模板或任何隐藏/显示它下面的按钮,基于它是否被选中。

为了简化我需要完成的工作,我有一个List,我想将它绑定到一个控件,并且它看起来尽可能接近上面的图像。

我该如何实现这一点以及XAML和后面的代码?

+0

我只是试图让一个自定义的ItemTemplate,但我没有走得很远。我遇到的问题是我不确定如何为每个Resolution对象动态添加按钮。它几乎就像,我需要在每个冲突 – TheJediCowboy

回答

1

下面是如何根据您Conflict对象可以动态创建数据模板,并添加按钮的例子:

public DataTemplate BuildDataTemplate(Conflict conflict) 
    { 
     DataTemplate template = new DataTemplate(); 

     // Set a stackpanel to hold all the resolution buttons 
     FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel)); 
     template.VisualTree = factory; 

     // Iterate through the resolution 
     foreach (var resolution in conflict.Resolutions) 
     { 
      // Create a button 
      FrameworkElementFactory childFactory = new FrameworkElementFactory(typeof(Button)); 

      // Bind it's content to the Name property of the resolution 
      childFactory.SetBinding(Button.ContentProperty, new Binding("Name")); 
      // Bind it's resolve method with the button's click event 
      childFactory.AddHandler(Button.ClickEvent, new Action(() => resolution.Resolve()); 

      // Append button to stackpanel 
      factory.AppendChild(childFactory); 
     } 

     return template; 
    } 

您可以在许多不同的方式做到这一点,这只是其中之一。 我没有测试它,但是这应该足以让你开始:)

好运

+0

每个分辨率对象的“中继器”如何设置?这是在ListView上设置的吗?这看起来像我所需要的,但我试图测试它,并不知道如何设置它,以便我可以测试它。 – TheJediCowboy

+0

我知道它的工作原理,但奇怪的是,SetBinding(..)调用绑定到冲突名称,而不是解析名称,所以我使用SetValue并传入分辨率名称。 – TheJediCowboy

+0

@CitadelCSAlum SetBinding()通过xaml完全像绑定机制一样工作,并相应地处理它的当前dataContext。因此,为了使'Name'的绑定显示分辨率的名称,你需要将你的'Resolutions'集合绑定到一些ItemsControls,比如'ListBox \ DataGrid'或'ItemsControl'本身,并应用这个'DataTemplate'到它。 –