我有一個WPF應用程序,我想通過用刪除線TextDecoration顯示它們來裝飾邏輯刪除的項目(在TreeView中保存)。在TreeViewItem樣式觸發器中TextDecorations不應用於TextBlock
我可以在觸發時成功應用前景色,但是當我嘗試設置TextDecorations時,它沒有任何效果。
下面是一些示例代碼,可以重現問題。首先,XAML:
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<EventSetter Event="TreeViewItem.MouseRightButtonDown" Handler="tvw_MouseRightButtonUp"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsDeleted}" Value="True">
<!--<Setter Property="TextBlock.Foreground" Value="red" />-->
<Setter Property="TextBlock.TextDecorations" Value="Underline" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
這裏是C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Globalization;
namespace StrikethroughTest {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
ObservableCollection<ViewModel> model = BuildModel();
tvw.ItemsSource = model;
}
private ObservableCollection<ViewModel> BuildModel() {
ObservableCollection<ViewModel> toplevel = new ObservableCollection<ViewModel>();
ViewModel root = new ViewModel("Root");
toplevel.Add(root);
for (int i = 1; i < 5; ++i) {
ViewModel child = new ViewModel("Child " + i);
root.AddChild(child);
for (int j = 1; j < 5; ++j) {
ViewModel leaf = new ViewModel("Leaf " + i + "," + j);
child.AddChild(leaf);
}
}
return toplevel;
}
private void tvw_MouseRightButtonUp(object sender, MouseButtonEventArgs e) {
ViewModel item = tvw.SelectedItem as ViewModel;
if (item != null) {
ShowMenu(item, tvw);
}
}
private void ShowMenu(ViewModel item, FrameworkElement source) {
ContextMenu menu = new ContextMenu();
MenuItem mnuDelete = new MenuItem();
mnuDelete.Header = "Delete";
mnuDelete.Click += new RoutedEventHandler((src, e) => { item.IsDeleted = true; });
menu.Items.Add(mnuDelete);
source.ContextMenu = menu;
}
}
public class ViewModel : ViewModelBase {
private bool _expanded;
private bool _selected;
private bool _deleted;
private ObservableCollection<ViewModel> _children;
public ViewModel(string caption) {
this.Caption = caption;
_children = new ObservableCollection<ViewModel>();
}
public void AddChild(ViewModel child) {
_children.Add(child);
}
public bool IsExpanded {
get { return _expanded; }
set { SetProperty("IsExpanded", ref _expanded, value); }
}
public bool IsSelected {
get { return _selected; }
set { SetProperty("IsSelected", ref _selected, value); }
}
public bool IsDeleted {
get { return _deleted; }
set { SetProperty("IsDeleted", ref _deleted, value); }
}
public ObservableCollection<ViewModel> Children {
get { return _children; }
}
public String Caption { get; set; }
}
public abstract class ViewModelBase : INotifyPropertyChanged {
protected bool SetProperty<T>(string propertyName, ref T backingField, T value) {
var changed = !EqualityComparer<T>.Default.Equals(backingField, value);
if (changed) {
backingField = value;
RaisePropertyChanged(propertyName);
}
return changed;
}
protected void RaisePropertyChanged(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
當某人選擇樹節點時,右鍵單擊並選擇刪除,我希望標題被刪除。在我的真實應用程序中,每個TreeViewItem都有一個圖標,爲簡潔起見我省略了它們,儘管它看起來沒有什麼區別。
有沒有人有任何想法,爲什麼這不工作?
謝謝,完美的作品!我想我認爲這是因爲我用'TextBlock'爲我的setter屬性添加了前綴,它會以某種方式將它神奇地應用於與該類型匹配的TreeViewItem的所有後代子節點。我想我仍然有辦法理解繼承模型。感謝您的鏈接,我會去看看。 – David 2010-08-05 02:24:26