I have a list box that should be filed when user click on Button,
sometimes the data loaded is quickly, and sometimes it take some time... Is there a simple way to load some animation like a clock, or something which can give the user indication that the process is running?
I use mvvm with button commands
<ListBox Width="30"
Visibility="{Binding IsDataLoaded,
Converter= {StaticResource BooleanToVisibilityConverter}}"
ItemsSource="{Binding Collection}"
FontSize ="15"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DarkGray" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Content="Go" Command="{Binding GoCommand}" IsEnabled="{Binding IsGoEnabled}" IsDefault="True" Width="60"
/>
Sounds like you're looking for a BusyIndicator like in the Extended Toolkit.
Related
I can not clean the text property of a TextBox when the user clicks inside it. The TextBox is inside a HierarchicalDataTemplate but the trigger doesn't work.
My code is as follows:
<HierarchicalDataTemplate x:Key="FoldersTemplate"
DataType="{x:Type vm:FolderViewModel}"
ItemsSource="{Binding Children}">
<Border>
<Grid>
<TextBox>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Name}" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Text" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
</HierarchicalDataTemplate>
The action I would like to happen is that when the user clicks on the text, it disappears. How can I solve this?
Thanks a lot.
I have a WPF datagrid using the WpfToolkit version 3.5.40128.1
For one cell I raise a PropertyChanged event that the viewmodel has a listener for, and determines if the value is duplicated to the other values. If it is duplicated, a state is set on the object and the cell is put into an error state.
So a user can enter Priority in the first record to 2 and the second field to 2 and the second value is in error.
When the user changes the error field all works as expected.
When the user changes the first '2' to 1 the second field is no longer duplicated and the flag is cleared. However, no matter what I do, the field remains in error. I have tried the following:
1) I added a PropertyChanged event call on the field even though it is in an ObservableCollection. This caused a regular check for duplicate values but did not remove the red outline.
2) I added event styles for both ValidationErrors==true as well as ValidationErrors==false. This sounded hopeful but it only clears the tooltip it does not clear the red outline.
3) I added a PropertyChanged call on the state boolean when it's value changes.
Playing with the field myself manually in the form, if I enter and exit the field it remains in error. If I enter the field and re-enter '2' the error state goes away.
I'm at a loss now as to what else to do! Any suggestions on additional things to try would be helpful.
Below is the style and definitions of the datagrid. Priority is the only field being validated.
<!-- style to apply to DataGrid TextBlock -->
<Style x:Key="DataGridTextBlockStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="ToolTipService.ShowDuration"
Value="20000"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value=""/>
</Trigger>
</Style.Triggers>
</Style>
<!-- style to apply to DataGrid CheckBox -->
<Style x:Key="DataGridCheckBoxStyle" TargetType="{x:Type CheckBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="ToolTipService.ShowDuration"
Value="20000"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value=""/>
</Trigger>
</Style.Triggers>
</Style>
<!-- style to apply to DataGrid TextBox in edit mode -->
<Style x:Key="CellEditStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="ToolTipService.ShowDuration"
Value="20000"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value=""/>
</Trigger>
</Style.Triggers>
</Style>
<!-- style to apply to DataGrid Checkbox in edit mode -->
<Style x:Key="CheckboxEditStyle" TargetType="{x:Type CheckBox}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="ToolTipService.ShowDuration"
Value="20000"/>
</Trigger>
</Style.Triggers>
</Style>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="345*"/>
<ColumnDefinition Width="88*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" VerticalAlignment="Top"
Margin="2,2,2,0" Header="Region Selection"
BorderBrush="White" BorderThickness="0" Grid.ColumnSpan="2">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical" Height="120"
VerticalAlignment="Top" Background="White">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="5,5,5,5" Height="101" >
<wpftk:DataGrid x:Name="SegmentGrid"
IsEnabled="True"
AutoGenerateColumns="False"
VerticalScrollBarVisibility="Auto"
Height="90"
ItemsSource="{Binding SegmentList}" CanUserAddRows="False" CanUserDeleteRows="False" >
<wpftk:DataGrid.Columns>
<!-- The Region Name Column -->
<wpftk:DataGridTextColumn Header="Name"
Width="265"
Binding="{Binding RegionName}" />
<!-- The Priority Column -->
<wpftk:DataGridTemplateColumn Header="Priority" Width="60">
<wpftk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource DataGridTextBlockStyle}"
Text="{Binding Priority, Mode=TwoWay,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</wpftk:DataGridTemplateColumn.CellTemplate>
<wpftk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox>
<TextBox.Text>
<Binding Path="Priority"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True" >
</Binding>
</TextBox.Text>
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource CellEditStyle}" />
</TextBox.Style>
</TextBox>
</DataTemplate>
</wpftk:DataGridTemplateColumn.CellEditingTemplate>
</wpftk:DataGridTemplateColumn>
<!-- The Write To Cartridge Column -->
<wpftk:DataGridTemplateColumn Header="Write To Cartridge" Width="80">
<wpftk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource DataGridCheckBoxStyle}"
IsChecked="{Binding WriteToCartridge, Mode=TwoWay,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</wpftk:DataGridTemplateColumn.CellTemplate>
<wpftk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<CheckBox>
<CheckBox.IsChecked>
<Binding Path="WriteToCartridge"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True"
ValidatesOnExceptions="True" >
</Binding>
</CheckBox.IsChecked>
<CheckBox.Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource CheckboxEditStyle}" />
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</wpftk:DataGridTemplateColumn.CellEditingTemplate>
</wpftk:DataGridTemplateColumn>
</wpftk:DataGrid.Columns>
</wpftk:DataGrid>
</ScrollViewer>
</StackPanel>
</Grid>
</GroupBox>
Needed to expose a new method inside the object for INotifyPropertyChanged.
This allowed us to examine all of the objects in the array, and when we changed the value we called it from the object rather than from the viewmodel. This caused the automatic finding and clearing of any object that was duplicated within the array.
I would like to set Triggers for the controls in a DataTemplate. Whenever I set a property of the control within the DataTemplate, it seems not working. However, If do not set the property within the TextBlock inside the DataTemplate, then I can see the effect of Trigger in the style (it works). I am not sure whether using Style Triggers with DataTemplate is good or not! The XAML is below;
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock" x:Key="BlockOf">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="ExtraBold" />
<Setter Property="FontSize" Value="22" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
...........
DataTemplate for the button,
<Button.ContentTemplate>
<DataTemplate DataType="Button">
<TextBlock Style="{DynamicResource BlockOf}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
FontStyle="Italic" FontSize="9"/>
</DataTemplate>
</Button.ContentTemplate>
I can see two problems here. First one is that current trigger will work only for TextBlock inside Button, not over whole Button. You can change that by using DataTrigger with RelativeSource binding. Second problem is that even when mouse is over TextBlock Style.Trigger cannot overwrite local value that you set against TextBlock so you need to bring default values as Setter into your Style. Check Dependency Property Setting Precedence List
<Style TargetType="TextBlock" x:Key="BlockOf">
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontSize" Value="9"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsMouseOver}" Value="True">
<Setter Property="FontWeight" Value="ExtraBold" />
<Setter Property="FontSize" Value="22" />
</DataTrigger>
</Style.Triggers>
</Style>
and then TextBlock simply
<TextBlock Style="{DynamicResource BlockOf}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
Here is what I am trying to accomplish:
I have a series of small images (24x24) indicating various system statuses. When a user rolls over of the images (e.g. a system alert image) I want a popup to display the first 5 alerts and a More... option (if there are more than 5 alerts). While the list is displayed, I want the user to be able to select one of the alerts or the More option and display the details.
The problem I am having is:
I cannot prevent the popup from disappearing when the mouse leaves the image to select an item.
Here is a segment of XAML from my User Control I am using to display the popup.
<Image x:Name="SmallImage"
Source="{Binding ElementName=root, Path=ImageSource}"
Height="{Binding ElementName=root, Path=Height}"
Width="{Binding ElementName=root, Path=Width}"
Grid.Row="0" />
<Popup Name="ItemPopup"
AllowsTransparency="True"
PopupAnimation="Fade"
HorizontalOffset="-35"
VerticalOffset="0"
Grid.Row="1">
<Popup.Style>
<Style TargetType="{x:Type Popup}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
<DataTrigger.Setters>
<Setter Property="IsOpen" Value="True" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<Border x:Name="MyBorder" BorderBrush="#72777F" Background="White" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5">
<Grid>
<Label Content="This is your list of items."></Label>
</Grid>
</Border>
</Popup>
This is because your Trigger will fire everytime the IsMouseOver Property will change and in case Trigger condition fails it will set the Property to its default i.e false in this case. You will need two Triggers here, one for opening the popup in case of IsMouseOver is true and second is to keep popup open if IsMouseOver becomes false and Popup was already open.
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
<DataTrigger.Setters>
<Setter Property="IsOpen" Value="True" />
</DataTrigger.Setters>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=SmallImage, Path=IsMouseOver, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="False"/>
<Condition Binding="{Binding IsOpen, RelativeSource={RelativeSource Self}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsOpen" Value="True" />
</MultiDataTrigger>
</Style.Triggers>
Hei,
Im creating a button what has a checkbox on top of it. Now when user hovers over the checkbox with a mouse i would like to change the text on the button.
Here's what i have currently:
<Button Grid.Row="1" Margin="0,0,136,12" Name="btnRefresh" Height="28" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="120" Click="btnRefresh_Click">
<Grid Width="111">
<CheckBox Height="16" HorizontalAlignment="Left" Margin="0,2,0,0" Name="cbAutoRefresh" VerticalContentAlignment="Center">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Content" Value="Auto Refresh" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<Label Name="btnLabel" Margin="32,-4,25,-4">Refresh</Label>
</Grid>
</Button>
But like this it changes the content of the checkbox, how can i change the btnLabel content?
Currently you're just modifing the style of the ComboBox, thats why the Trigger just changes the Content of your ComboBox.
To listen to other controls properties in a Trigger, you can use Databinding like so:
<Label Name="btnLabel" Margin="32,-4,25,-4">
<Label.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=comboBoxName, Path=IsMouseOver}" Value="False"
<Setter Property="Content" Value="Refresh"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=comboBoxName, Path=IsMouseOver}" Value="True"
<Setter Property="Content" Value="Auto Refresh"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>