- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想扩展选项卡控件以具有可关闭的选项卡项目。
我找到了 Kent 的这个 WPF 解决方案:
On the WPF TabControl - can I add content next to the tab headers?
我在 Blend 中打开了现有 Silverlight tabcontrol 的副本。然而,结构看起来与 WPF 选项卡控件完全不同。我无法将其直接放入 Silverlight 控件模板中。
有人知道我的好资源吗?
最佳答案
我之前也遇到过同样的问题,然后我决定使用扩展 TabControl
.我不知道在哪里找到它,但没关系,现在它在我的项目中。
有了这个 TabControl
我可以在 ViewModel 集合中添加或删除项目,我的更改将反射(reflect)在用户界面上。
MyTabControl.cs
public class MyTabControl : TabControl
{
public MyTabControl()
: base()
{
this.SelectionChanged += OnSelectionChanged;
}
#region Tabs with databinding and templates
/// <summary>
/// Template for a TabItem header
/// </summary>
public DataTemplate TabHeaderItemTemplate
{
get { return (DataTemplate)GetValue(TabHeaderItemTemplateProperty); }
set { SetValue(TabHeaderItemTemplateProperty, value); }
}
public static readonly DependencyProperty TabHeaderItemTemplateProperty =
DependencyProperty.Register("TabHeaderItemTemplate", typeof(DataTemplate), typeof(MyTabControl), new PropertyMetadata(
(sender, e) =>
{
((MyTabControl)sender).InitTabs();
}));
/// <summary>
/// Template for a content
/// </summary>
public DataTemplate TabItemTemplate
{
get { return (DataTemplate)GetValue(TabItemTemplateProperty); }
set { SetValue(TabItemTemplateProperty, value); }
}
public static readonly DependencyProperty TabItemTemplateProperty =
DependencyProperty.Register("TabItemTemplate", typeof(DataTemplate), typeof(MyTabControl), new PropertyMetadata(
(sender, e) =>
{
((MyTabControl)sender).InitTabs();
}));
/// <summary>
/// Source of clr-objects
/// </summary>
public IEnumerable MyItemsSource
{
get
{
return (IEnumerable)GetValue(MyItemsSourceProperty);
}
set
{
SetValue(MyItemsSourceProperty, value);
}
}
public static readonly DependencyProperty MyItemsSourceProperty =
DependencyProperty.Register("MyItemsSource", typeof(IEnumerable), typeof(MyTabControl), new PropertyMetadata(
(sender, e) =>
{
MyTabControl control = (MyTabControl)sender;
INotifyCollectionChanged incc = e.OldValue as INotifyCollectionChanged;
if (incc != null)
{
incc.CollectionChanged -= control.MyItemsSourceCollectionChanged;
}
control.InitTabs();
incc = e.NewValue as INotifyCollectionChanged;
if (incc != null)
{
incc.CollectionChanged += control.MyItemsSourceCollectionChanged;
}
}));
/// <summary>
/// Selected item as object
/// </summary>
public object MySelectedItem
{
get { return (object)GetValue(MySelectedItemProperty); }
set { SetValue(MySelectedItemProperty, value); }
}
// Using a DependencyProperty as the backing store for MySelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MySelectedItemProperty =
DependencyProperty.Register("MySelectedItem", typeof(object), typeof(MyTabControl), new PropertyMetadata(
(sender, e) =>
{
MyTabControl control = (MyTabControl)sender;
if (e.NewValue == null)
control.SelectedItem = null;
else
{
var tab = control.Items.Cast<TabItem>().FirstOrDefault(ti => ti.DataContext == e.NewValue);
if (tab != null && control.SelectedItem != tab)
control.SelectedItem = tab;
}
}));
private void InitTabs()
{
Items.Clear();
if (MyItemsSource != null && MyItemsSource.OfType<object>().Any())
{
int i = 0;
foreach (var item in MyItemsSource)
{
var newitem = new TabItem();
if (TabItemTemplate != null)
newitem.Content = TabItemTemplate.LoadContent();
if (TabHeaderItemTemplate != null)
newitem.Header = TabHeaderItemTemplate.LoadContent();
newitem.DataContext = item;
Items.Add(newitem);
}
VisualStateManager.GoToState(this, "Normal", true);
}
else VisualStateManager.GoToState(this, "NoTabs", true);
}
private void MyItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
if (e.NewStartingIndex > -1)
{
foreach (var item in e.NewItems)
{
var newitem = new TabItem();
if (TabItemTemplate != null)
newitem.Content = TabItemTemplate.LoadContent();
if (TabHeaderItemTemplate != null)
newitem.Header = TabHeaderItemTemplate.LoadContent();
newitem.DataContext = item;
Items.Add(newitem);
}
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
if (e.OldStartingIndex > -1)
{
var ti = (TabItem)this.Items[e.OldStartingIndex];
Items.RemoveAt(e.OldStartingIndex);
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace)
{
Items.RemoveAt(e.OldStartingIndex);
var newitem = new TabItem();
if (TabItemTemplate != null)
newitem.Content = TabItemTemplate.LoadContent();
if (TabHeaderItemTemplate != null)
newitem.Header = TabHeaderItemTemplate.LoadContent();
newitem.DataContext = e.NewItems[0];
Items.Add(newitem);
Items.Insert(e.NewStartingIndex, newitem);
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
{
InitTabs();
}
}
#endregion
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var si = e.AddedItems.Cast<TabItem>().FirstOrDefault();
if (si != null)
this.MySelectedItem = si.DataContext;
else this.MySelectedItem = null;
}
}
<my:MyTabControl MyItemsSource="{Binding Items}" MySelectedItem="{Binding SelectedITem}">
<my:MyTabControl.TabHeaderItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" VerticalAlignment="Center"/>
<Button Content="X" Margin="3" Width="20" Height="20" Grid.Column="1"
Command="{Binding RequestCloseCommand}"/>
</Grid>
</DataTemplate>
</my:MyTabControl.TabHeaderItemTemplate>
<my:MyTabControl.TabItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Content}"/>
</DataTemplate>
</my:MyTabControl.TabItemTemplate>
</my:MyTabControl>
MyItemsSource
和
MySelectedItem
, 因为这个
TabControl
使用对象,而不是
TabItem
.
public class MainViewModel
{
public MainViewModel()
{
this.Items = new ObservableCollection<TabItemViewModel>
{
new TabItemViewModel("Tab 1", OnItemRequestClose),
new TabItemViewModel("Tab item 2", OnItemRequestClose)
};
}
public ObservableCollection<TabItemViewModel> Items { get; set; }
public void OnItemRequestClose(TabItemViewModel item)
{
this.Items.Remove(item);
}
}
public class TabItemViewModel
{
public TabItemViewModel(string title, Action<TabItemViewModel> onClose)
{
this.Title = title;
this.RequestCloseCommand = new DelegateCommand(_ => onClose(this));
//Just a demontration
this.Content = "Test content "+title;
}
public string Title { get; set; }
public ICommand RequestCloseCommand { get; set; }
public object Content { get; set; }
}
关于银光 4 : Making Closeable Tabitems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4828661/
我是 selenium 的新手。我在使用 Selenium WebDriver 时遇到了一些问题。 我想使用 Selenium WebDriver 打开网站,例如 www.filpkart.com 我
在阅读一些 Java 源代码时,我遇到了这一行: ((Closeable) some_obj).close(); some_obj 显然是一个实现了 Closeable 接口(interface)的类
我最近查看了 jdk 1.8 的 src.zip 文件,发现了一些很奇怪的东西。 public interface Closeable extends AutoCloseable 既然AutoClos
我是单元测试的新手。 我应该如何为这个方法编写 JUnit 测试? public static void close(Closeable closeable) { if (closea
我问了this question yesterday .我想我得到了正确的答案,但其他答案之一给我留下了一个问题。如果我有这样的代码: File file = new File("somefile.t
我已经实现了自己的可关闭 JTabbedPane(基本上遵循了 here 的建议 - 通过扩展 JTabbedPane 并覆盖一些方法并调用 setTabComponentAt(...))。它完美地工
我想扩展选项卡控件以具有可关闭的选项卡项目。 我找到了 Kent 的这个 WPF 解决方案: On the WPF TabControl - can I add content next to the
我的整个系统有一个静态 HashMap,其中包含一些对象的引用;我们称之为myHash 。这些对象仅在我需要它们时才会实例化,例如 private static HashMap directories
我不明白。例如我们在代码中有一个 OutputStream 类型的变量,当我们停止使用它时我们应该调用它的 close() ,为什么它没有以这种方式实现:GC 在清理时调用 close() 本身这个变
有时我必须编写将自己注册为其他对象的监听器的对象。良好的编程实践表明我们应该始终注销此类监听器。通过使类实现 Closeable 并在 close() 中注销监听器来尝试强制执行此类行为是一种好习惯吗
我正在学习 Java,我找不到关于 implements Closeable 和 implements AutoCloseable 接口(interface)的任何好的解释。 当我实现 interfa
我有一个 Map如果从 map 中删除了一个键,我想关闭 Closeable .通常我有这样的东西: Closeable c = map.remove(key); c.close(); 我的 Ecli
有人可以向我解释这里发生了什么以及顺序是什么吗?。输出对我来说没有任何意义。 输出为 T 1 IOE F。 代码是: import java.io.Closeable; import java.io.
在 Android 应用中,我将此代码添加到 onCreate() Closeable sss = new Socket(); if (!(sss instanceof Closeab
我想知道为什么我会在新的 eclipse Juno 上收到这个警告,尽管我认为我正确地关闭了所有内容。您能告诉我为什么我会在以下代码中收到此警告吗? public static boolean cop
假设我们有两个 Closeable bean: @Component public class CloseableBean1 implements Closeable { private Bu
为什么他们要添加 AutoCloseable 并更改 Closeable 如下: public interface Closeable extends AutoCloseable { publ
我正在尝试创建一个管理多个 Closeable 资源的 Java 类。 C++ 解决方案简单明了,并且可以轻松扩展到更多资源: class composed_resource { resour
我遇到了类似于 this one 的问题,除了 java.util.Scanner。我有这个静态方法: public static void close(final Closeable c) {
当我运行我的 Android 应用程序时,出现以下错误: 10-12 16:46:44.719 2710-2719/? E/StrictMode: A resource was acquired at
我是一名优秀的程序员,十分优秀!