【问题标题】:Setting a treeview items text colour in realtime based on a ViewModel property基于 ViewModel 属性实时设置树视图项目文本颜色
【发布时间】:2013-03-27 09:07:54
【问题描述】:

在我的 WPF 应用程序中,我使用的是 MVVM 模式。我的视图有一个树视图,我绑定了一个 observableCollection 对象,如下定义。我想要做的是在绑定对象将它的脏属性设置为 true 时更改树项名称的颜色。当我第一次填充树时,我可以让它设置颜色,但是当属性在 false 和 true 之间变化时,它不会反映变化。

public class HierarchicalItem
{
    private readonly ObservableCollection<HierarchicalItem> _children = new ObservableCollection<HierarchicalItem>();

    public ViewModelBase ViewModel { get; set; }

    public string Name
    {
        get { return ViewModel.ViewModelName; }
    }

    public ICollection<HierarchicalItem> Children
    {
        get { return _children; }
    }

    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            if (_isSelected)
                EventSystem.Publish(new SelectedViewModelMessage { SelectedViewModel = ViewModel });
        }
    }

    public bool IsDirty
    {
        get { return ViewModel.IsDirty; }
    }
}

这是树视图 xaml:

    <TreeView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Views}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="True"/>
                <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=OneWayToSource}" />
            </Style>
        </TreeView.ItemContainerStyle>

        <TreeView.Resources>

            <HierarchicalDataTemplate DataType="{x:Type local:HierarchicalItem}" ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}">

                    <TextBlock.Style>
                        <Style TargetType="TextBlock">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsDirty}" Value="True">
                                    <Setter Property="Foreground" Value="Red" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>

                </TextBlock>
            </HierarchicalDataTemplate>

        </TreeView.Resources>
    </TreeView>

这是绑定到树的集合:

    private readonly ObservableCollection<HierarchicalItem> _views = new ObservableCollection<HierarchicalItem>();
    public ObservableCollection<HierarchicalItem> Views
    {
        get { return _views; }
    }

在 HierarchicalItem 集合中引用的 ViewModel 都派生自公开“IsDirty”属性的基类。这肯定会改变状态,所以我不确定我是否犯了编码错误,或者我想要实现的目标是否无法以这种方式完成。这些类都使用“INotifyPropertyChanged”接口。这是 ViewModel 基类中的“IsDirty”属性:

public class ViewModelBase : ValidatableModel
{
    #region Properties

    private bool _isDirty;
    public bool IsDirty
    {
        get { return _isDirty; }
        protected set
        {
            _isDirty = value;
            OnPropertyChanged("IsDirty");
        }
    }

 .
 .
 .
 Etc

【问题讨论】:

    标签: c# mvvm treeview wpf-4.5


    【解决方案1】:

    这是因为您的 HierarchicalItem(您遇到问题的那个)没有对其 IsDirty 属性使用完整的 INPC 方法。视图模型可以,但这还不够,因为 DataTemplate 将使用 HierarchicalItem 的 IsDirty 属性,因此也需要完整的 INPC 属性

    改成这个应该没问题。

    private bool _isDirty;
    public bool IsDirty
    {
        get { return _isDirty; }
        protected set
        {
            _isDirty = value;
            OnPropertyChanged("IsDirty");
        }
    }
    

    尽管对于您的用例,您需要想出一些方法来触发它。或者您可以尝试的另一件事是将 HierarchicalItem DataTemplate 中的绑定更改为此

    <DataTrigger Binding="{Binding ViewModel.IsDirty}" Value="True">
    

    【讨论】:

    • 感谢您的回复。我猜它会像这样直截了当。我的固定代码现在按预期工作。
    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    相关资源
    最近更新 更多