WPF 的 转换器可以动态绑定吗
TreeView的节点中的文本框使用了Converter={StaticResource IsLeafNodeConverter},但这个转换器只能对原来的数据有效,在程序运行后再往里添加节点,发现新增节点没有使用转换器。
试了下Dynamic Resources,直接跑不了
想问下有办法让新增的节点也能用转化器吗
<Window x:Class="WpfApp.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp"
xmlns:conv="clr-namespace:WpfApp.ViewModels"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<conv:IsLeafNodeConverter x:Key="IsLeafNodeConverter" />
<!-- 使用conv前缀引用转换器 -->
</Window.Resources>
<Grid>
<TreeView ItemsSource="{Binding TreeNodes}" Margin="37,66,353,66">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildNodes}">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=NodeName, Mode=TwoWay}" Margin="0,0,5,0"></TextBox>
<TextBlock Text="权重"/>
<TextBox Text="{Binding Path=Weight, Mode=TwoWay}" Margin="0,0,5,0" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding Path=DataContext.updateScoreCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="{Binding Path=.}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock Text="分数"/>
<!-- 静态资源(Static Resource),动态资源(Dynamic Resources)。这两者的区别是:静态资源在第一次编译后即确定其对象或值,之后不能对其进行修改。动态资源则是在运行时决定,当运行过程中真正需要时,才到资源目标中查找其值。因此,我们可以动态地修改它。由于动态资源的运行时才能确定其值,因此效率比静态资源要低。 -->
<!-- https://blog.csdn.net/yangwenxue1989/article/details/81385856 -->
<!-- https://www.itbaoku.cn/post/1981662.html -->
<TextBox Text="{Binding Path=Score, Mode=TwoWay}" Margin="0,0,5,0" IsEnabled="{Binding Path=. ,Converter={StaticResource IsLeafNodeConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding Path=DataContext.updateScoreCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="{Binding Path=.}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Button Content="添加子指标" Command="{Binding Path=DataContext.addChildNodeCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="{Binding Path=.}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<Button Content="测试双向绑定" Command="{Binding buttun_clickCommand}" HorizontalAlignment="Left" Margin="615,255,0,0" VerticalAlignment="Top" />
<Button Content="添加一级指标" Command="{Binding addTopNodeCommand}" HorizontalAlignment="Left" Margin="371,36,0,0" VerticalAlignment="Top" />
<TextBlock HorizontalAlignment="Left" Margin="37,36,0,0" TextWrapping="Wrap" VerticalAlignment="Top"><Run Language="zh-cn" Text="总分数"/><LineBreak/><Run Language="zh-cn"/></TextBlock>
<TextBlock HorizontalAlignment="Left" Margin="92,36,0,0" TextWrapping="Wrap" Text="{Binding TotalScore}" VerticalAlignment="Top"/>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using WpfApp.Models;
namespace WpfApp.ViewModels
{
public class IsLeafNodeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 检查传入的对象是否为TargetNode类型
if (value!=null && value is TargetNode node)
{
Debug.WriteLine("判断该节点是否是叶子节点");
// 如果节点有ChildNodes属性且为空,则为叶子节点
return node.ChildNodes == null || node.ChildNodes.Count == 0;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}