北海,要多想 2024-04-25 15:22 采纳率: 0%
浏览 14

WPF 的 转换器可以动态绑定吗

WPF 的 转换器可以动态绑定吗
TreeView的节点中的文本框使用了Converter={StaticResource IsLeafNodeConverter},但这个转换器只能对原来的数据有效,在程序运行后再往里添加节点,发现新增节点没有使用转换器。
试了下Dynamic Resources,直接跑不了
想问下有办法让新增的节点也能用转化器吗

img

img


<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();
        }
    }
}


  • 写回答

4条回答 默认 最新

  • DTcode7 优质创作者: 前端开发技术领域 2024-05-30 19:39
    关注

    答案引用自chatgpt生成,望对题主有所帮助/启发;若有帮助,还望采纳!

    WPF(Windows Presentation Foundation)的转换器可以动态绑定。在WPF中,转换器用于将一个属性的值转换为另一个属性的值。这种转换可以在运行时进行,因此可以实现动态绑定。

    基本概念:

    1. 转换器:在WPF中,转换器是一种用于将一个属性的值转换为另一个属性的值的工具。它们通常用于实现数据绑定和数据验证等功能。
    2. 动态绑定:动态绑定是指在运行时根据对象的属性值自动更新界面的过程。在WPF中,可以使用数据绑定和依赖属性来实现动态绑定。

    作用说明:

    1. 转换器可以将一个属性的值转换为另一个属性的值,从而实现数据的双向绑定。例如,可以将一个文本框的文本属性绑定到另一个控件的背景颜色属性,当文本框的文本发生变化时,背景颜色也会自动更新。
    2. 转换器可以实现更复杂的逻辑,例如将一个布尔值转换为一个字符串,或者将一个数值范围映射到另一个数值范围等。
    3. 转换器可以在运行时进行,这意味着可以在程序运行过程中动态地改变转换规则,从而实现动态绑定。

    代码示例:
    以下是一个简单的WPF示例,演示了如何使用转换器实现动态绑定。在这个示例中,我们将一个滑块的Value属性绑定到一个矩形的宽度属性,并使用一个转换器将滑块的Value属性转换为矩形的宽度属性。

    <Window x:Class="WpfApp1.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"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Slider x:Name="slider" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="200" ValueChanged="Slider_ValueChanged"/>
            <Rectangle x:Name="rectangle" Fill="Blue" HorizontalAlignment="Left" Margin="10,50,0,0" VerticalAlignment="Top" Width="{Binding ElementName=slider, Path=Value, Converter={StaticResource WidthConverter}}"/>
        </Grid>
    </Window>
    
    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApp1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
            {
                // 在这里可以处理滑块值变化的逻辑
            }
        }
    
        public class WidthConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value is double width)
                {
                    return width * 2; // 将滑块的值乘以2作为矩形的宽度
                }
                return DependencyProperty.UnsetValue;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    

    在这个示例中,我们创建了一个名为WidthConverter的转换器类,该类实现了IValueConverter接口。在Convert方法中,我们将滑块的值乘以2作为矩形的宽度。然后,我们在XAML中使用{Binding ElementName=slider, Path=Value, Converter={StaticResource WidthConverter}}将滑块的Value属性绑定到矩形的Width属性,并指定使用我们创建的转换器。这样,当滑块的值发生变化时,矩形的宽度也会自动更新。

    评论

报告相同问题?

问题事件

  • 创建了问题 4月25日