WPF IValueConverter doesn't work. How Can I Fix it?

c00012 736 Reputation points
2021-02-17T09:28:07+00:00

Hello,

I'm posting a question because of something make me stuck in writing WPF app.

I want to change foreground of TextBox when value is over the baseline.

so, I wrote a code about value converter as follows:

using System.Text;
using System.Windows.Data;
using System.Windows.Media;

namespace WpfApp1.Converters
{
public class AgeToForegroundConverter : IValueConverter
{
// Called when converting the Age to a Foreground brush
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Only convert to brushes...
if (targetType != typeof(Brush)) { return null; }

        // DANGER! After 25, it's all down hill...
        int age = int.Parse(value.ToString());
        return age > 25 ? Brushes.Red : Brushes.Black;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // should not be called in our example
        throw new NotImplementedException();
    }
}

public class Base16Converter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Convert to base 16
        return ((int)value).ToString("x");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Convert from base 16
        return int.Parse((string)value, System.Globalization.NumberStyles.HexNumber);
    }
}

}

And, I bound these converters to Textboxes as follows:

<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"
xmlns:local="clr-namespace:WpfApp1.Converters"
Title="MainWindow"
Width="200"
Height="135"
mc:Ignorable="d">
<Window.Resources>
<local:AgeToForegroundConverter x:Key="ageConverter"/>
<local:Base16Converter x:Key="base16Converter"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center">
Name:
</TextBlock>
<TextBox
Name="nameTextBox"
Text="{Binding Path=Name}"
Grid.Row="0"
Grid.Column="1"
Margin="5" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center">
Age:
</TextBlock>
<TextBox
Name="ageTextBox"
Foreground="{Binding Path=Age, Converter={ StaticResource ageConverter}}"
Text="{Binding Path=Age, Converter={StaticResource base16Converter}}"
Grid.Row="1"
Grid.Column="1"
Margin="5" />
<Button
Name="birthdayButton"
Foreground="{Binding Path = Foreground, ElementName=ageTextBox}"
Grid.Row="2"
Grid.Column="1"
Margin="5">
Birthday
</Button>
</Grid>
</Window>

I didn't get any error messages from above code. but these codes didn't work when I run the app.
if someone help me to fix this, I would be very appreciated.

thanks,

seihyung

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,777 questions
{count} votes

Accepted answer
  1. DaisyTian-1203 11,621 Reputation points
    2021-02-18T09:07:19.63+00:00

    What does your IValueConverter doesn't work refer to? Did the data binding fail or the converter fail?

    Data binding fail: Please add below class and this.DataContext = new MyModel(); in xaml.cs:

     public class MyModel : INotifyPropertyChanged  
        {  
            public MyModel()  
            {  
                 
            }  
            private int age;  
            private string name;  
      
            public event PropertyChangedEventHandler PropertyChanged;  
      
            public int Age  
            {  
                get { return age; }  
                set  
                {  
                    age = value;  
                    if (this.PropertyChanged != null)  
                    {  
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("age"));  
                    }  
                }  
            }  
            public string Name  
            {  
                get { return name; }  
                set  
                {  
                    name = value;  
                    if (this.PropertyChanged != null)  
                    {  
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("name"));  
                    }  
                }  
            }  
        }  
    

    Converter fail: I test your converters, but the second converter in ageTextBox doesn't work. I add triggers in your xam as below:

     <Window.Resources>  
            <local:AgeToForegroundConverter x:Key="ageConverter"/>  
            <local:Base16Converter x:Key="base16Converter"/>  
        </Window.Resources>  
        <Grid>  
            <Grid.RowDefinitions>  
                <RowDefinition Height="Auto" />  
                <RowDefinition Height="Auto" />  
                <RowDefinition Height="Auto" />  
                <RowDefinition Height="Auto" />  
                <RowDefinition Height="Auto" />  
            </Grid.RowDefinitions>  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition Width="Auto" />  
                <ColumnDefinition Width="*" />  
            </Grid.ColumnDefinitions>  
      
            <TextBlock Grid.Row ="0" Grid.Column ="0" Margin ="5" VerticalAlignment =" Center"> Name:</TextBlock>  
            <TextBox Name ="nameTextBox" Text ="{Binding Path = Name}" Grid.Row ="0" Grid.Column ="1" Margin ="5" />  
            <TextBlock Grid.Row="1" Grid.Column="0" Margin="5" VerticalAlignment="Center">Age:</TextBlock>  
      
            <TextBox Name="ageTextBox" Foreground="{Binding Path=Age, Converter={ StaticResource ageConverter}}" Text="{Binding Path=Age, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1"    Margin="5">  
                <TextBox.Style>  
                    <Style TargetType="TextBox">  
                        <Setter Property="Visibility" Value="Visible"></Setter>  
                        <Style.Triggers>  
                            <DataTrigger Binding="{Binding ElementName=ageTextBox,Path=Visibility}" Value="Hidden">  
                                <Setter Property="Text" Value="AAA" />  
                            </DataTrigger>  
                              
                            <DataTrigger Binding="{Binding ElementName=ageTextBox1,Path=Visibility}" Value="Hidden">  
                                <Setter Property="Visibility" Value="Visible" />  
                                <Setter Property="Background" Value="LightBlue"></Setter>  
                            </DataTrigger>  
      
                            <DataTrigger Binding="{Binding ElementName=ageTextBox1,Path=Visibility}" Value="Visible">  
                                <Setter Property="Visibility" Value="Hidden" />  
                            </DataTrigger>  
                              
                        </Style.Triggers>  
                    </Style>  
                </TextBox.Style>  
            </TextBox>  
            <Button Name="birthdayButton" Foreground="{Binding Path = Foreground, ElementName=ageTextBox}" Content="Birthday"  Grid.Row="2" Grid.Column="1" Margin="5"></Button>  
            <TextBox Name="ageTextBox1" Foreground="{Binding Path=Age, Converter={ StaticResource ageConverter}}"   Text="{Binding Path=Age, Converter={StaticResource base16Converter}}" Grid.Row="1" Grid.Column="1" Margin="5">  
                <TextBox.Style>  
                    <Style TargetType="TextBox">  
                        <Setter Property="Visibility" Value="Hidden"></Setter>  
                        <Style.Triggers>  
                            <DataTrigger Binding="{Binding ElementName=ageTextBox,Path=Foreground}" Value="Red">  
                                <Setter Property="Visibility" Value="Visible" />  
                                <Setter Property="Background" Value="Yellow"></Setter>  
                            </DataTrigger>  
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text}" Value="">  
                                <Setter Property="Visibility" Value="Hidden" />  
                            </DataTrigger>  
                        </Style.Triggers>  
                    </Style>  
                </TextBox.Style>  
      
            </TextBox>  
        </Grid>  
    

    Please point out if I misunderstand your question.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.