I have a button that has its content (text) set dynamically via a style against a backing property as below.
<Button>
<Button.Style>
<Style>
<Setter Property="Button.Content" Value="Advanced Search" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsAdvancedSearch}" Value="True">
<Setter Property="Button.Content" Value="Standard Search" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I need to change this button to display just a hyperlink with the same dynamic text. Like this:
<Button>
<Button.Template>
<ControlTemplate>
<TextBlock>
<Hyperlink>
Standard Search
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Button.Template>
</Button>
Is there a way to set the hyperlink's text (inline or some other tag) dynamically via a style still?
I haven't been able to get access to it via XAML. I got it working with a normal binding on a textblock inside the hyperlink but that is creating a redundant property on the viewmodel really.
You can embed another TextBlock inside your Hyperlink and bind it:
<TextBlock>
<Hyperlink>
<TextBlock Text="{Binding LinkText}" />
</Hyperlink>
</TextBlock>
Solution was to simply apply the style to an inner Textblock.
<Button x:Name="SwitchSearchType">
<Button.Template>
<ControlTemplate>
<TextBlock>
<Hyperlink>
<Hyperlink.Inlines>
<TextBlock>
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="Advanced Search" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsAdvancedSearch}" Value="True">
<Setter Property="TextBlock.Text" Value="Standard Search" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Button.Template>
</Button>
<GridViewColumn Header="{x:Static lang:Lang.wName}" CellTemplate="{StaticResource Template_DebitAccount}" />
And use into skin file
<DataTemplate x:Key="Template_DebitAccount">
<Border Padding="3" >
<TextBlock Text="{Binding wDebitAccountName}" Style="{StaticResource TextStyle_Path}">
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.Base_PopPageCommand , RelativeSource={RelativeSource AncestorType=ListView}}" >
<MouseBinding.CommandParameter>
<MultiBinding Converter="{StaticResource MultiValueBindingConverter}">
<Binding Source="AgentSummary" />
<Binding Path="Link_Text"/>
</MultiBinding>
</MouseBinding.CommandParameter>
</MouseBinding>
</TextBlock.InputBindings>
</TextBlock>
</Border>
</DataTemplate>
Given:
<Hyperlink x:Name="uriEmailAddress" Click="Hyperlink_Click"></Hyperlink>
Code:
string e = Properties.Settings.Default.Email;
uriEmailAddress.NavigateUri = new Uri("mailto:" + e);
InlineCollection ic = uriEmailAddress.Inlines;
ic.Add(new Run(e));
Related
Referencing to this question: WPF Databinding: How do I access the "parent" data context?
I wanna do something similiar, but for the header of a Groupbox (because the header does not concern with the Box is being disabled and thus is always black while the rest is light gray. This looks a bit strange to me if all the content of the box is gray, the above is gray, but the box title itself stays black.
So I tried to use the approach mentioned in the linked question by flq to simply bind the isEnabled property of the header textblock to the isEnabled property of the groupbox but it seems that my binding at some point fails and I don't know where and why exactly.
heres my current code:
<GroupBox Header="Change Steps" Grid.Row="2" Grid.ColumnSpan="3" Name="gbChangeSteps">
<GroupBox.Style>
<Style TargetType="GroupBox">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontWeight="Bold" Height="19" Foreground="Black" IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=isEnabled}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupBox.Style>
<!-- ... (some non relevant Content)-->
</GroupBox>
after additional research I found the post Disable groupBox including the groupBox name in WPF
that lead me, in combination with Properties->Create Databinding->Binding type->UIElement to the solution that fixed both problems, the one this question was about and the original one that lead to entire restyling, which was that letters like the small g got messed up in the header.
This is the code that fixed the issue:
<GroupBox.Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontWeight="Bold" Height="19" IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UIElement}}}">
<TextBlock.Style>
<Style>
<Style.Triggers>
<Trigger Property="Control.IsEnabled" Value="False">
<Setter Property="Control.Foreground" Value ="#FF6D6D6D" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupBox.Style>
I am doing my first project using wpf. I really need your help and suggestion. Thanks in advance.
I am building a screen, which has two listboxes A & B. Listbox A is binding to items load from database. listbox B is binding to a statics list. When user selects an item in listbox A, the associate item will be highlighted in listbox B. I am doing it by using MultiBinding in a listboxtitem. I'd like to pass selected data object and listboxitem content. The Convert() will take these two variables and check them. If match, it will return true to IsSelected property of item and highlight it. But it seems item content (statics string) can't be passed to converter(). What should I do?
see my xaml code:
<ListBox Name="AbsenseCode" ItemsSource="{Binding absenseCodeItems}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Margin="20,0,20,5" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected">
<Setter.Value>
<MultiBinding Converter="{StaticResource IsItemSelected}">
<Binding ElementName="FilterListbox" Path="SelectedItem"/>
<Binding Path="Content"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
when debugging, the second binging variable, content of item, is "{DependencyProperty.UnsetValue}".
this is a few months old, but I had a similar situation.
First, build a iMultiValueConveter that will compare two values and return the result to a string. "true" or "false" or "yes" or "no".
then in the XAML, define a style that can be triggered by the converter return. In this, ListBoxB has an ellipse where the fill will be green if the values match, red if they dont:
<Window.Resources>
<myNamespace:IsEqualConverter x:Key="IsEqualConverter" />
</Window.Resources>
<ListBox Name="ListBoxA" ItemsSource="{Binding}">
</ListBox>
<ListBox Name="ListBoxB" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<StackPanel>
<StackPanel.Resources>
<!-- style triggered by converter result -->
<Style TargetType="Ellipse" x:Key="EllipseStyle">
<Setter Property="Fill" Value="#E5E5E5" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=result,Path=Text}" Value="true">
<Setter Property="Fill" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=result,Path=Text}" Value="false">
<Setter Property="Fill" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Ellipse Height="50" Width="50" Style="{StaticResoure EllipseStyle}" />
<TextBlock x:Name="value0" Text="{Binding ElementName=ListBoxA,Path=SelectedItem.(Whatever),Mode=OneWay}" />
<TextBlock x:Name="value1" Text="{Data Binding you want to compare to}" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock x:Name="result">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource IsEqualConverter}">
<Binding ElementName="value0" Path="Text" />
<Binding ElementName="value1" Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</ListBox.ItemTemplate>
</ListBox>
This Button looks fine (see screenshot) when defining the image as done below. Note that the shield shaped icon with the letter 'T' is visualized correctly.
<Button Command="w:MainWindow.BrowseTorrentSite">
<StackPanel>
<Image Source="../icons/kickasstorrent.png" />
</StackPanel>
</Button>
When I want to rely on the buttons enabled state, the icon gets mirrored.
<StackPanel
Orientation="Horizontal"
FlowDirection="RightToLeft">
<Button
x:Name="KatButton"
Command="w:MainWindow.BrowseTorrentSite">
<StackPanel>
<Image>
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"
Value="True">
<Setter Property="Source" Value="../icons/kickasstorrent.png" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"
Value="False">
<Setter Property="Source" Value="../icons/kickasstorrent_disabled.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button>
</StackPanel>
Note the shield shaped icon with the letter 'T' is now mirrored.
What is responsible for mirroring the icon?
If somebody has tips to debug this in whatever way possible, feel free to point me in the right direction!
The problem is in the parent StackPanel. If the StackPanel is defining the FlowDirection from right to left, the Image definition inherits this property which results in the flipped icon.
To solve this problem redefine left to right on the image itself.
<StackPanel
Orientation="Horizontal"
FlowDirection="RightToLeft">
<Button>
<Image FlowDirection="LeftToRight">
<Image.Style>
<!-- etc etc -->
</Image.Style>
</Image>
</Button>
</StackPanel>
I am using the Xceed datagrid for WPF. Today I was trying to change the background of the whole row if one of its column "SA" has the some value or not null. I wrote the following piece of code in XAML with a converter function in code behind:
<xcdg:DataGridControl.Resources>
<Style TargetType="{x:Type xcdg:DataRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource newConverter}, Path=Cells[SA].Content}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</xcdg:DataGridControl.Resources>
To my surprise, as soon as I load the grid for the first time, the data in the SA column is nowhere to be seen. However, once I scroll down a bit, till the point that row which is supposed to have data for the column is not visible, and then when I scroll up again to see that row, I can see the value in that column as well as the background changed.
What am I doing wrong?
Use simple binding and avoid converter/template
<TextBlock Text="{Binding}"></TextBlock>
To fill color in your column use this or the following code:
<xcdg:Column Title="Unit Price" FieldName="UnitPrice" ReadOnly="True">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<DockPanel LastChildFill="false" x:Name="UnitPrice">
<TextBlock Text="{Binding}"></TextBlock>
<Image x:Name="img" Width="16" Height="16" DockPanel.Dock="Right"
Margin="2,0,0,0" Visibility="Collapsed"
ToolTip="Unit Price is Undefined." VerticalAlignment="Center"
HorizontalAlignment="Left" />
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="0.00">
<Setter TargetName="img" Property="Visibility" Value="Visible" />
<Setter TargetName="UnitPrice" Property="Background" Value="Pink" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>
Well i guess it's easy my scenario is having 2 elements:
ListBox and Button:
<ListBox Name="BannedItemsListBox"
Margin="5"
MinWidth="100"
MaxWidth="100" " Height="
204" ItemsSource="{Binding Path=BannedItems, Mode=TwoWay}"></ListBox>
<Button Name="RemoveBannedItemsButton"
Margin="5"
MinWidth="65"
Height="22"
Click="RemoveBannedItemButton_Click">Remove</Button>
I want to bind the IsEnabled property button to be true only if Item from ListBox is selected (focused) in XAML
I tried
IsEnabled="{Binding ElementName=BannedSourcesListBox, Path=TouchesDirectlyOver.Count}"
but no go.
What does the selection have to do with the Touches? (Also the ElementName is off)
I would try this:
IsEnabled="{Binding SelectedItems.Count, ElementName=BannedItemsListBox}"
Explanation: Basically the binding system tries to convert the input to the property at hand, a boolean, so when it gets an integer, 0 will be converter to false, anything higher to true. So the Button will be enabled if one or more items are selected.
<Button Content="Button"
Height="23"
HorizontalAlignment="Left"
Margin="138,12,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75"
Click="button1_Click">
<Button.Style>
<Style>
<Setter Property="Button.IsEnabled"
Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lstTest , Path=SelectedItem}"
Value="{x:Null}">
<Setter Property="Button.IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>