I`d like select between combobox and textbox depending on ViewModel. In the view model i have two properties one of them should be null and the other not null.
enter image description here
I´m not sure if that´s exactly what you want to do. As CarbineCoder already said, some more code would be helpful. If you want to show only one of both controls you could create two properties called for example tbVisibility and cbVisibility. If you want to show the ComboBox, then cbVisibility has to be "visible" and tbVisibility has to be "hidden".
XAML would like that:
<StackPanel Orientation="Horizontal">
<!--This is visible if tbVisibility is "visible" and cbVisibility is "hidden"-->
<Label Width="100" Content="label" Visibility="{Binding tbVisibility}"></Label>
<TextBox Width="184" Text="Textbox" Visibility="{Binding tbVisibility}"></TextBox>
<!--This part is visible if cbVisibility is "visible" and tbVisibility is "hidden"-->
<Label Width="100" Content="label" Visibility="{Binding cbVisibility}"></Label>
<TextBox Width="184" Visibility="{Binding cbVisibility}"></TextBox>
</StackPanel>
You only have to define in you code which property is visibile and which is not.
Related
I've recently moved from Windows Forms to WPF. I started with Reed Copsey's series 'Better User and Developer Experiences – From Windows Forms to WPF with MVVM'. On the 4th part of the series, the following code should fill text boxes with data:
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Feed.Title, Mode=OneWay}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Feed.Link.AbsoluteUri, Mode=OneWay}" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Feed.Description, Mode=OneWay}"/>
I tried to use this template-of-code to 'update a target (TextBlock.Text) as the source (TextBox.Text) updates', and that was my full XAML code:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="608.134" Width="768.284">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Height="28" Margin="442,56,0,0" VerticalAlignment="Top" Width="139" Click="Button_Click_1"/>
<TextBox x:Name="TextBox1" HorizontalAlignment="Left" Height="28" Margin="56,56,0,0" TextWrapping="Wrap" Text="TextBox1" VerticalAlignment="Top" Width="237"/>
<TextBlock HorizontalAlignment="Left" Height="66" Margin="56,168,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="285"
Text="{Binding Path=TextBox1.Text, Mode = OneWay}"/>
</Grid>
</Window>
The expected value for the text of the TextBlock was "TextBox1" (TextBox1.Text), but the TextBlock text was actually null!
So, I checked what triggers source updates, and decided to change the binding mode to TwoWay, but I got the same result!
At last, I found "How to: Control When the TextBox Text Updates the Source" that shows how to do that. According to what Reed Copsey said in this part of his series:
Less code means less to maintain, less to test, and less to worry about.
and according to the source found on MSDN:
<Label>Enter a Name:</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource myDataSource}" Path="Name"
UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
<Label>The name you entered:</Label>
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
I'll be typing (roughly) the same amount of code. And such a mission (to change TextBlock by TextBox changes) can be accomplished using the normal event handlers. So my questions are:
If the same mission can be accomplished with roughly the same amount of code, what makes WPF data binding so special?
What was wrong with my first code?
In the above MSDN code, they had to type an XAML code for both source and target. If I wanted the source to be a value inside a class, is it possible to accomplish such mission? And how?
Any help will be appreciated,
Thanks in advance.
You first attempt is incorrect as the Binding path is relative to the DataContext of the TextBlock. You are trying to bind to a specific element, so you can use ElementName to specify the source and then the path is relative to this:
Text="{Binding ElementName=TextBox1, Path=Text}"
The idiomatic approach to WPF is to use MVVM. In this situation, both the TextBox and TextBlock would be bound to a property on the View Model.
The changing of the text in the TextBox would update this property which in turn would update the TextBlock. Your View Model is free from WPF View concerns and can be unit tested without involving WPF.
Good Morning,
I need to make the label below to where the Tag property will be the same as the content.
Basically If the content is "this label's content" then the Tag property should be "this label's content" as well.
I have tried quite a few things however this is my most recent attempt:
<Label x:Name="label" HorizontalContentAlignment="Center" Background="{Binding Background, ElementName=ColorForBGG}" Tag="{Binding RelativeSource={RelativeSource Self}, Path=x.Content}"/>
you can do this directly using the Element-
<Label x:Name="label" Content="Label" HorizontalContentAlignment="Center" Background="{Binding Background, ElementName=ColorForBGG}" Margin="62,59,0,0" VerticalAlignment="Top" Tag="{Binding Content, ElementName=label}"/>
I am doing a project where I need a timer with drop shadow. I managed to figure out a way to do the drop shadow with 2 labels, but my problem now is that I need to give both the same name to act in the exact same way in all situation WITHOUT having duplicated code. Is this possible?
<Grid>
<Label x:Name="time" MouseDoubleClick="time_MouseDoubleClick" HorizontalAlignment="Center" FontFamily="Old English Text MT" Margin="0,5,0,0" FontSize="22" Content="00:00:00" FontWeight="Bold" Foreground="Black">
<Label.RenderTransform>
<TranslateTransform X="1.5" Y="1"/>
</Label.RenderTransform>
</Label>
<Label x:Name="time2" MouseDoubleClick="time_MouseDoubleClick" HorizontalAlignment="Center" FontFamily="Old English Text MT" Margin="0,5,0,0" FontSize="22" Content="00:00:00" FontWeight="Bold" Foreground="White"/>
</Grid>
This is how the code looks to make the drop shadow. Is there a way around this? Or is there a way like in HTML where I can define a "class" name?
You don't need two labels. You need DropShadowEffect:
<Label Content="00:00:00">
<Label.Effect>
<DropShadowEffect/>
</Label.Effect>
</Label>
It seems that you in actual fact need a drop-shaddow effect, another implementation to have two controls update based on the same property might lie in binding.
In the initialize method of the codebehind file set the DataContext.
DataContext = this;
Change your xaml to bind to a common string property.
<Grid>
<Label x:Name="time" MouseDoubleClick="time_MouseDoubleClick" HorizontalAlignment="Center" FontFamily="Old English Text MT" Margin="0,5,0,0" FontSize="22" Content="{Binding Time}" FontWeight="Bold" Foreground="Black">
<Label.RenderTransform>
<TranslateTransform X="1.5" Y="1"/>
</Label.RenderTransform>
</Label>
<Label x:Name="time2" MouseDoubleClick="time_MouseDoubleClick" HorizontalAlignment="Center" FontFamily="Old English Text MT" Margin="0,5,0,0" FontSize="22" Content="{Binding Time}" FontWeight="Bold" Foreground="White"/>
</Grid>
(The content property now includes binding)
Ensure that you have a property in the codebehind to support the binding
public string Time {get;set;}
Your code-behind (.cs file) should implement the INotifyPropertyChanged interface, and your property should Raise the Event.
Then by changing the Time property, the XAML will automatically update.
How can i get the total of a field in a XamDataGrid? I want to show the sum of all records' $ amounts in a textbox NOT in the grid itself. Here's how i did this for the number of items in the grid, which works:
<Label Content="Total Line Items"/>
<TextBox Text="{Binding ElementName=xamDataGrid1, Path=Records.Count, Mode=OneWay}" Grid.Column="1" />
So how can i sum a certain field? Is it possible to do anything like:
<Label Content="Total Salaries: " Grid.Column="2" />
<TextBox Grid.Column="3" BorderBrush="Red" Text="{Binding ElementName=xamDataGrid1, Path=**SUM(SALARYFIELD)**, Mode=OneWay}"/>
I do not want the SummaryDefintions method (I know how to do that already) and i must not refer to the grid in code-behind etc. What can i put in the binding, or what can i replace SUM(SALARYFIELD) with to make this work?
I found the answer i was looking for. Had to involve XamDataGrid's Summary definitions, but I can not show them and then bind to their data as below:
<TextBox Text="{Binding ElementName=xamDataGrid1, Path=Records.SummaryResults[1].Value, StringFormat=C, Mode=OneWay}"
I have a TextBox in a Stackpanel, as in the code below
<StackPanel x:Name="EtenStack" Visibility="{Binding Path=Sort, ConverterParameter=Eten, Converter={StaticResource convertEten}}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Bereidingstijd"/>
<TextBox Height="23" Width="150" Text="{Binding Path=Time, TargetNullValue='', Mode=TwoWay}"/>
</StackPanel>
When the Visibility is set to Visible in my converter, my textbox doesn't update it's Text property, even though the Property gets it's correct value (tested by showing a MessageBox with the Property).
Any thoughts?
The Time property will need to be either a Dependency Property with the right binding or on a class that Implements the INotifyPropertyChanged Interface, for the Time property, in order for the update to occur "Automatically."