Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
2.00/5 (3 votes)
See more:
The problem with the below code is when I am entering the value in any one of the textboxes , the button is getting enabled and what I want is that the button should be enabled only when all the textbox has some value. Please help me if I am missing anything.
XML
<Window.Resources><Style TargetType="TextBox">
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="Text" Value=""/>
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="Button.IsEnabled" Value="False"/>
                    </MultiTrigger.Setters>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid Margin="0,192,0,0">
        <TextBox x:Name="txt_Titel" Margin="137,-149,260,241"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="137,-91,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="137,-63,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
        <Button Content="Transfer" />
    </Grid>
</Window>
Posted
Updated 21-May-16 22:42pm
v2
Comments
Sergey Alexandrovich Kryukov 21-May-16 10:36am    
TextBox always "has value". You need to formulate exact criteria. Yes, multi-condition triggers can be used (and, for more complex criteria, may be impractical or even useless, in contrast to simple code behind). "unable to achieve" is not informative. Please read carefully:
What have you tried so far?

—SA
vickyanand25005 21-May-16 11:32am    
Hi Sergey Sorry for the incomplete question. I have updated the question with what I have tried so far.Please take a look and let me know what i am missing. Thanks:)
Sergey Alexandrovich Kryukov 21-May-16 12:00pm    
Now it's much better, thank you. Next time, show complete XAML. You can shorted it inside, but keep it well-formed XML. It is not well-formed now. I answered the question, please see Solution 2.
—SA
vickyanand25005 21-May-16 11:21am    
[Unwanted code removed... — SA]
Suvendu Shekhar Giri 21-May-16 11:45am    
Agree with @Sergy, I haven't worked much on WPF but seems a simple task if you do this at code behind.

You can use a MultiBinding for that purpose. You can create an IMultiValueConverter as follows:


C#
public class HasAllTextConverter: IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool res = true;

        foreach (object val in values)
        {
            if (string.IsNullOrEmpty(val as string))
            {
                res = false;
            }
        }

        return res;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and, use it with MultiBinding as follows:


HTML
<StackPanel>
    <StackPanel.Resources>
        <local:HasAllTextConverter x:Key="HasAllTextConverter" />
    </StackPanel.Resources>
    <TextBox Name="tb1" />
    <TextBox Name="tb2" />
    <Button Content="Button 1" >
        <Button.IsEnabled>
            <MultiBinding Converter="{StaticResource HasAllTextConverter}">
                <Binding ElementName="tb1" Path="Text" />
                <Binding ElementName="tb2" Path="Text" />
            </MultiBinding>
        </Button.IsEnabled>
    </Button>
</StackPanel>

[EDIT: Add a solution without code-behind.]


If you don't want to use code-behind, you can do it with a MultiTrigger (but, since panel's triggers can contain only an EventTrigger, you have to wrap it with a DataTemplate or something else that can contain it and, contains the involved elements too). Something like:


HTML
<ContentControl Content="{Binding}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBox Name="tb3" />
                <TextBox Name="tb4" />
                <Button Name="btn2" Content="Button 2" />
            </StackPanel>
            <DataTemplate.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition SourceName="tb3" Property="TextBox.Text" Value="" />
                        <Condition SourceName="tb4" Property="TextBox.Text" Value="" />
                    </MultiTrigger.Conditions>
                    <Setter TargetName="btn2" Property="IsEnabled" Value="False" />
                </MultiTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>
 
Share this answer
 
v2
Comments
vickyanand25005 22-May-16 12:54pm    
Thanks Shmuel :-). Can we do it without using the converter?
Shmuel Zang 23-May-16 2:13am    
Yes. It can be done. I added an example of doing it without a converter (or any code-behind). See the updated solution.
The first missing part I can see is that you created the style in the dictionary but did not use it anywhere.

First, you need to give a key to your style. Let's assume you want to name it "myTextBoxStyle", then:
HTML
<Style x:Key="myTextBoxStyle" TargetType="TextBox">
   <!-- ... -->
</Style>

Then, for the TextBox using the style you have a to add the attribute Style="{StaticResource myTextBoxStyle}".

[EDIT: incorrect statement removed in response to comment:]

Actually, without key your project could not even build.

—SA
 
Share this answer
 
v5
Comments
Shmuel Zang 22-May-16 8:58am    
According to the Style.TargetType Property documentation, setting a TargetType property to a style without setting an x:Key, implicitly sets the x:Key to that type (and implicitly applied to the controls of that type, if you didn't set other style for them...). So, it looks like that isn't the problem...
Anyway, IMO style isn't the right approach here. It seems like MultiBinding is a better approach here (see my solution).
Sergey Alexandrovich Kryukov 22-May-16 9:12am    
Thank you, I checked up the build without x:Key, yes, it is not required. I fixed my answer accordingly.
Thank you for correcting me.

Anyway, the bug I described is different. It's not about not having the key, it's about not actually using the style.
As to the use of MultiTrigger, it's perfectly suitable.

—SA
Hi Sergey i ahve tried this let me know where i am doing wrong.
XML
<Grid Margin="0,192,0,0">
        <TextBox x:Name="txt_Titel" Margin="137,-149,260,241"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="137,-91,0,0" Text="" VerticalAlignment="Top" Width="120"/>
        <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="137,-63,0,0" Text="" VerticalAlignment="Top" Width="120"/>
        <Button Content="Transfer">
            <Button.Style>
                <Style>
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="TextBox.Text" Value=""/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="Button.IsEnabled" Value="False"/>
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                        
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 22-May-16 8:22am    
First of all, this is not a solution. If you need to add code, use "Improve question".
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900