avaloniaui / avalonia.xaml.behaviors Goto Github PK
View Code? Open in Web Editor NEWPort of Windows UWP Xaml Behaviors for Avalonia Xaml.
License: MIT License
Port of Windows UWP Xaml Behaviors for Avalonia Xaml.
License: MIT License
Just replase your code for List box tab in your sample
https://github.com/wieslawsoltes/AvaloniaBehaviors/tree/master/samples/DraggableDemo
<TabItem Header="ListBox">
<ListBox Classes="draggable">
<ListBox.Styles>
<Style Selector="ListBoxItem > TextBlock">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="ListBoxItem:not(:dragging)">
<Setter Property="Transitions">
<Setter.Value>
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.1" />
</Transitions>
</Setter.Value>
</Setter>
</Style>
</ListBox.Styles>
<ListBoxItem>
<TextBlock Text="Item1" />
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="Item2" />
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="Item3" />
</ListBoxItem>
<ListBoxItem>
<ComboBox>
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
</ComboBox>
</ListBoxItem>
<ListBoxItem>
<Button>Hello!</Button>
</ListBoxItem>
</ListBox>
</TabItem>
Hi,
I need some help with ChangePropertyAction. whenever I want to use it as in following example, its not working and I do not know why. I hope Somebody can steer me to right path.
Thanks
<TextBlock Classes="DefaultStyle" Text="{Binding HouseBalanceInformation.Bilance, StringFormat=Bilance: {0}}" Name="HouseBilance">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding HouseBalanceInformation.Bilance}" ComparisonCondition="LessThan" Value="0">
<ia:ChangePropertyAction TargetObject="{Binding $self}" PropertyName="Background" Value="#ff0000" />
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding HouseBalanceInformation.Bilance}" ComparisonCondition="GreaterThan" Value="0">
<ia:ChangePropertyAction TargetObject="{Binding $self}" PropertyName="Background" Value="#00ff00" />
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
Xaml:
<ia:DataTriggerBehavior Binding="{Binding Condition}"
ComparisonCondition="Equal"
Value="False">
<ia:ChangePropertyAction TargetObject="{Binding #PosterImageBackground}"
PropertyName="Background"
Value="{DynamicResource SystemControlBackgroundBaseMediumBrush}" />
</ia:DataTriggerBehavior>
When I replace DynamicResource with StaticResource everything works.
Unable using scrollbar if scrollview is inside ListBoxItem when draggablevirtualizing or draggable classes is applied to parent Listbox
Hello,
In a mvvm combobox, the EventTriggerBehavior SelectionChanged is triggered before the SelectedItem
<ComboBox x:Name="cmbMainLang"
assists:ComboBoxAssist.Label="{Binding Hint}"
PlaceholderText="{Binding Hint}"
MaxDropDownHeight="200"
Margin="0 40 0 0"
DataContext="{Binding UILanguagesComboBox}"
Items="{Binding Items}"
SelectedItem="{Binding Selected}">
<Interaction.Behaviors>
<EventTriggerBehavior EventName="SelectionChanged">
<InvokeCommandAction Command="{Binding SelectCommand}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</ComboBox>
This lead to an unsynchonized combobox value & command
Thanks
Hello,
For now, there are no way to pass parameters to a CallMethodAction (like in the InvokeCommandAction)
It could be a nice improvement :)
Thanks
I try to set the Foreground property of a TextBox via a DataTriggerBehavior and ChangePropertyAction:
<TextBox Name="LastName" Text="{Binding Person.LastName}"> <i:Interaction.Behaviors> <ia:DataTriggerBehavior Binding="{Binding Person.LastName, Converter={StaticResource toLowerStringConverter}}" ComparisonCondition="Equal" Value="schulz"> <ia:ChangePropertyAction TargetObject="{Binding #LastName}" PropertyName="Foreground" Value="#FF0000" /> </ia:DataTriggerBehavior> </i:Interaction.Behaviors> </TextBox>
But the TextBox doesnt show the letters at all, although you can see that it has content because you can see some "spaces" inside the TextBox:
I attached an example solution.
AvaloniaTest.zip
I am using the latest version 0.9.12
The current pack of behaviors is very nice, but i would like to have an analog of MultiDataTrigger from WPF. Is that possible?
Is there an example for shift+clicking or ctrl+clicking a button? I want my button to have one command, but if I shift+click the button I want it to invoke a different command
Trying to run an app with the nightly build throws this error
<PackageReference Include="Avalonia" Version="11.0.999-cibuild0030725-beta" />
<PackageReference Include="Avalonia.Xaml.Interactions" Version="11.0.999-build20230221-01" />
System.TypeInitializationException: The type initializer for 'Avalonia.Xaml.Interactions.Core.EventTriggerBehavior' threw an exception.
---> System.MissingMethodException: Method not found: 'Avalonia.StyledProperty1<!!1> Avalonia.AvaloniaProperty.Register(System.String, !!1, Boolean, Avalonia.Data.BindingMode, System.Func
2<!!1,Boolean>, System.Func`3<Avalonia.AvaloniaObject,!!1,!!1>)'.
I doesn't update the image source.
<Image Name="image" Source="../Assets/Loading.ico" MaxWidth="24" MaxHeight="24" Margin="4">
<Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding Updated^}" ComparisonCondition="Equal" Value="true">
<ChangePropertyAction TargetObject="{Binding #image}" PropertyName="Source" Value="../Assets/True.ico" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding Updated^}" ComparisonCondition="Equal" Value="false">
<ChangePropertyAction TargetObject="{Binding #image}" PropertyName="Source" Value="../Assets/False.ico" />
</DataTriggerBehavior>
</Interaction.Behaviors>
</Image>
But it works when I use text (emoji here).
<Label Name="label" Content="💤" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding Updated^}" ComparisonCondition="Equal" Value="true">
<ChangePropertyAction TargetObject="{Binding #label}" PropertyName="Content" Value="✅" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding Updated^}" ComparisonCondition="Equal" Value="false">
<ChangePropertyAction TargetObject="{Binding #label}" PropertyName="Content" Value="🛑" />
</DataTriggerBehavior>
</Interaction.Behaviors>
</Label>
IDropHandler.Leave is using RoutedEventArgs
instead of DragEventArgs
. As a workaround, you can cast to RoutedEventArgs e
to DragEventArgs
in the implementation.
Hi there,
I have an issue when I'm using a DataTriggerBehavior on ListboxItem.
I want just to set background (after that, my final purpose is to set template and contentTemplate) on listboxItem with ChangePropertyAction like this :
<ListBox
Items="{Binding Persons}"
SelectionMode="Multiple"
x:Name="ListPerson">
<Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding SelectedPerson}" Value="{x:Static enums:PersonType.SuperUser}">
<ChangePropertyAction TargetObject="{Binding #ListPerson.Items}" PropertyName="Background"
Value="Red" />
</DataTriggerBehavior>
</ListBox>
Did I missing something on the DataTriggerBehavior current behavior because the property won't change after DataTrigger ?
I have checked if the binding have the right value and it's that case.
After check, it's maybe related to this issue ? Can't use static object binding with DataTriggerBehavior
Thank in advance.
Using the EventTriggerBehavior from a combobox with the SelectionChanged event doesn't work as WPF interactivity implementation.
For example:
<ComboBox x:Name="ComboBoxSelection">
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="SelectionChanged"
SourceObject="{Binding #ComboBoxSelection}">
<interactions:InvokeCommandAction Command="{Binding Command}"
CommandParameter="{Binding SelectedItem.Content, ElementName=ComboBoxSelection}"/>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ComboBoxItem Content="1" />
<ComboBoxItem Content="2" />
</ComboBox>
In this case SelectedItem is not properly updated, so the value is always the previous selection.
Is it possible to apply/refer to a style in a ChangePropertyAction? I have this example XAML:
<Window.Styles>
<Style Selector="TextBox">
<Setter Property="Margin" Value="0,10,0,0"></Setter>
<Setter Property="Width" Value="100"></Setter>
<Setter Property="Foreground" Value="#000000"></Setter>
</Style>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="CornerRadius" Value="20"></Setter>
</Style>
</Window.Styles>
<StackPanel>
<TextBox Text="{Binding Person.FirstName}"></TextBox>
<TextBox Name="LastName" Text="{Binding Person.LastName}">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding Person.LastName, Converter={StaticResource toLowerStringConverter}}" ComparisonCondition="Equal" Value="schulz">
<ia:ChangePropertyAction TargetObject="{Binding #LastName}" PropertyName="Foreground" Value="#FF0000" />
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding Person.LastName, Converter={StaticResource toLowerStringConverter}}" ComparisonCondition="NotEqual" Value="schulz">
<ia:ChangePropertyAction TargetObject="{Binding #LastName}" PropertyName="Foreground" Value="#000000" />
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</TextBox>
<TextBox Text="{Binding Person.Age}"></TextBox>
<Button Width="100" Margin="0,10,0,0" Command="{Binding IncrementAge}">Age++</Button>
</StackPanel>
If Peron.LastName has a specific value i want the foreground color to be red, else I want it to have the default color in my application, black in this case. But I also defined the foreground color in a style for all TextBoxes(<Style Selector="TextBox">....) . So I would like to be able to refer to/apply this style in the ChangePropertyAction to not have the foreground color defined at several locations in the file.
Hello and thank you for this beautiful piece of software!
I noticed that async methods, returning Task, are not supported by CallMethodAction.
Is it difficult to add this possibility?
Thank you
The tree nodes (parent nodes) do not expand and collapse when ContextDragBehavior is being used.
When I remove ContextDragBehavior, the tree nodes can expand and collapse, but cannot drag and drop. Is it possible to be able to have both features available at the same time, Expand Collapse and Drag Drop.
I have listbox and I wanna bind command to listbox item. I try this:
<ListBox x:Name="MessageListBox" Grid.Row="1"
SelectionMode="Multiple"
IsVisible="{Binding IsMessageListBoxVisible}"
SelectedItem="{Binding ReceivedApplicationMessages.SelectedItem}"
SelectedItems="{Binding ReceivedApplicationMessagesHighlighted}"
Items="{Binding ReceivedApplicationMessages}"
AutoScrollToSelectedItem="False">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate DataType="subscriptions:SubscriptionsPageViewModel">
<TextBlock>
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="PointerPressed">
<InvokeCommandAction Command="{Binding ShowCommandsByTraceId}"></InvokeCommandAction>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
It doesn't work and I dont wanna know what to do. May you help me, please?
first of all this library is really really useful and I am happy with the state it is. 😄 However when I tested some performance in my App and I noticed that adding several hundred or thousand items to a ListBox.draggable
makes the UI nearly unusable. After having a deeper look I noticed that virtualization is disabled in the Styles
-Section:
<Style Selector=":is(ListBox).draggable">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
If I replace the StackPanel
with VirtualizingStackPanel
it works, but dragging an item and scrolling is buggy (I think this is the reason for disabling virtualization?)
I know that I can add my own logic which I already do (I use adorner instead of transforms) but maybe others will face the same issue also, that is why I decided to open this ticket here. If I find a good solution I'll open a PR for this.
Happy coding
Tim
Hi,
I have found an issue while using an InvokeCommandAction on ReactiveCommand :
Command requires parameters of type System.Reactive.Unit, but received parameter of type Avalonia.Controls.SelectionChangedEventArgs_
Example from DragAndDropSample :
<ListBox Items="{Binding Items}"
Classes="ItemsDragAndDrop">
<ListBox.ItemTemplate>
<DataTemplate DataType="vm:ItemViewModel">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ListBox.ItemTemplate>
<Interaction.Behaviors>
<EventTriggerBehavior EventName="SelectionChanged">
<InvokeCommandAction Command="{Binding TestCommand}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</ListBox>
public class MainWindowViewModel : ViewModelBase
{
private ObservableCollection<ItemViewModel> _items;
public ObservableCollection<ItemViewModel> Items
{
get => _items;
set => this.RaiseAndSetIfChanged(ref _items, value);
}
public ICommand TestCommand => ReactiveCommand.Create(AddTest);
public MainWindowViewModel()
{
_items = new ObservableCollection<ItemViewModel>()
{
new() { Title = "Item0" },
new() { Title = "Item1" },
new() { Title = "Item2" },
new() { Title = "Item3" },
new() { Title = "Item4" }
};
}
public void AddTest()
{
Items.Add(new ItemViewModel { Title = "Test" });
}
}
Is it possible to use ReactiveCommand with TriggerBehavior with InvokeCommandAction (It's working wpf projects) ?
Thank in advance.
I publish the app with Native aot, It will no work when I use Avalonia.xaml.behaviors. I try to add in rd.xaml, but it will failed to publish. How can i do if I wont to use avalonia.xaml.behaviors
When a DataTrigger and ChangePropertyAction are bound to the same object, the DataTrigger will call the ChangePropertyAction before the binding on the ChangePropertyAction has a chance to update.
Example code: (Button increments SelectedCount)
<Button Name="Button" Command="{Binding OnClicked}" Content="{Binding SelectedCount}"/>
<TextBlock Grid.Row="1">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding SelectedCount}" Value="0">
<ia:ChangePropertyAction Value="No items selected" PropertyName="Text"/>
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding SelectedCount}" Value="1">
<ia:ChangePropertyAction Value="1 item selected" PropertyName="Text"/>
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding SelectedCount}" Value="1" ComparisonCondition="GreaterThan">
<ia:ChangePropertyAction PropertyName="Text">
<ia:ChangePropertyAction.Value>
<Binding Path="SelectedCount" StringFormat="{}{0} items selected"/>
</ia:ChangePropertyAction.Value>
</ia:ChangePropertyAction>
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
Error CS0012 the "AvaloniaObject" type is defined in an Assembly that is not referenced. You should add a link to " Avalonia.Base versions=0.10.0.0, cultures=neutral, PublicKeyToken values=null"
using Avalonia.Controls;
using Avalonia.Xaml.Interactivity;
public class ButtonBehaviers : Behavior<TextBox> { }
Since these packages are preliminary and there are stable versions of Avalonia and Behaviors, I just wanted you to know about this conflict in advance.
Avalonia allows to bind to observables and tasks with caret ^
syntax, e.g. {Binding WhenFocused^}
.
Problem is, there is no easy way to subscribe to streams.
DataTriggerBehavior
doesn't work without value to compare to, so I have either to wrap Unit
observables (with e.g. IObservable<bool>
) or to shoehorn Unit.Default
into a binding.EventTriggerBehavior
seems more suitable for that, but currently it's concerned with events only.Ideally I'd like to write:
<ia:WhateverTriggerBehavior Binding="{Binding WhenFocused^}">
<iac:FocusControlAction/>
</ia:WhateverTriggerBehavior>
I could only find samples for a single click. Is there a behavior that triggers on a double click?
The following trigger setup never fires its actions:
<ia:DataTriggerBehavior
Binding="{Binding ShipAsset^, Converter={x:Static u:ObjectConverters.ToString}}"
ComparisonCondition="Equal"
Value="{x:Null}">
...
</ia:DataTriggerBehavior>
I can work around this by setting TargetNullValue on the binding to a dummy string, and then everything works great.
<ia:DataTriggerBehavior
Binding="{Binding ShipAsset^, Converter={x:Static u:ObjectConverters.ToString}, TargetNullValue=WTF}"
ComparisonCondition="Equal"
Value="WTF">
...
</ia:DataTriggerBehavior>
The culprit seems to be an explicit null check against DataTriggerBehavior.Value
within the OnValueChanged
handler.
The note says that there's a problem when the binding is initially null
, but value
is only used within the Compare()
method, which seems to be written to handle null
values just fine.
How do I invoke a command when a listbox item is double clicked?
<ListBox Items="{ Binding Accounts }" SelectedItem="{ Binding SelectedAccount }" ScrollViewer.VerticalScrollBarVisibility="Visible" Grid.Row="2">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="{ Binding AccountName }" Text="{ Binding AccountName }">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="DoubleTapped" SourceObject="{ Binding AccountName }">
<ia:InvokeCommandAction Command="{ Binding Login }" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This doesn't seem to work, but if I wrap the behavior inside a Button and change the SourceObject to the button it works normally.
Originally posted by IncPlusPlus September 13, 2022
Hi there. Thanks for making such an awesome library. I was searching around trying to find out how to make an item draggable in Avalonia and almost gave up until I found this. I've figured out how to make a single ListBox
item draggable. However, my SelectionMode
is set to multiple so multiple items can be selected. When I select multiple items and then start to drag, all items except the one I started the drag action on get deselected. Is there a way to make dragging respect the existing selection of items in a ListBox
?
I tried removing the drag & drop behavior and discovered that this issue seems to be with Avalonia specifically. If I start making a dragging motion, the selection is cleared.
I made a discussion post a few months ago asking about this. As far as I can tell, dragging multiple items in a ListBox
with SelectionMode="Multiple" is not possible. I've created this issue as an enhancement request.
Is it possible that support could be added for this scenario in the future? If not, do you know of a way I could avoid this issue? I was thinking maybe there was a way to stop the ListBoxItem
from getting the PointerPressedEvent
until it was followed by a PointerReleasedEvent
&& no drag had occurred. However, I'm not quite familiar enough with Avalonia to pull it off.
If a DataTriggerBehavior is bound with {Binding ..., Source={x:Static ...}}
, the OnValueChanged call happens before AttachedValue is set, so it fails. I tried saving the event and calling it again in OnAttached()
, but at this point the Value property on any ChangePropertyActions has not been set, so it still fails.
Example code (in BehaviorsTestApplication):
DataTriggerBehaviorControl.xaml
<Grid RowDefinitions="5*,*">
<Rectangle Name="DataTriggerRectangle" Grid.Row="0" Margin="5" Stroke="{DynamicResource GrayBrush}" StrokeThickness="5">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding ., Source={x:Static vm:MainWindowViewModel.TestInt}}"
ComparisonCondition="GreaterThan" Value="50">
<ia:ChangePropertyAction PropertyName="Fill" TargetObject="{Binding #DataTriggerRectangle}" Value="{DynamicResource YellowBrush}" />
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding ., Source={x:Static vm:MainWindowViewModel.TestInt}}" ComparisonCondition="LessThanOrEqual" Value="50">
<ia:ChangePropertyAction PropertyName="Fill" TargetObject="{Binding #DataTriggerRectangle}" Value="{DynamicResource BlueBrush}" />
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Rectangle>
<StackPanel Grid.Row="1" Margin="5,0,5,5" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Width="50" VerticalAlignment="Center" Foreground="{DynamicResource GrayBrush}" Text="{Binding ., Source={x:Static vm:MainWindowViewModel.TestInt}}" />
</StackPanel>
</Grid>
MainWindowViewModel.cs
public static int TestInt = 51;
The binding correctly updates the TextBox, but does not trigger the DataTriggerBehavior.
Hello everyone,
First of all I want to say thank you for this library!!! I have a question regarding DataTriggerBehavior: is it possible to use some transformation function on a binding value or have additional comparison conditions, for example in order to compare it case insensitive? example:
<StackPanel> <i:Interaction.Behaviors> <ia:DataTriggerBehavior Binding="{Binding Person.LastName}" ComparisonCondition="Equal" Value="foo"> <ia:ChangePropertyAction TargetObject="{Binding #LastName}" PropertyName="Foreground" Value="#FF0000" /> </ia:DataTriggerBehavior> </i:Interaction.Behaviors> <TextBox Name="LastName" Classes="important" Text="{Binding Person.LastName}"></TextBox> </StackPanel>
My goal is to compare Person.LastName case insensitive to foo.
Issue #17 was already about this, but the 'solution' (There wasn't really a solution posted) mentioned there doesn't work for me.
I still get the following warning during execution: [Binding] Error in binding to "Avalonia.Xaml.Interactions.Core.InvokeCommandAction"."Command": "Null value in expression ''." (Avalonia.Xaml.Interactions.Core.InvokeCommandAction #12001237)
The code does work (The double tap event triggers the command successfully), but emits this warning for each of the event triggers during runtime. I have exactly the same problem with a DataTrigger, but that one refuses to work at all.
Take this simple example:
Relevant XAML namespaces, for your convenience
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
xmlns:ia="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"
XAML
<TextBlock Name="driveLabel" Text="{Binding DisplayName}">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="DoubleTapped" SourceObject="{Binding #driveLabel}">
<ia:InvokeCommandAction CommandParameter="{Binding}" Command="{Binding DataContext.OpenDriveCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
C# code
public ReactiveCommand<MyViewModel, Unit> OpenDriveCommand { get; }
public MyConstructor()
{
this.OpenDriveCommand = ReactiveCommand.Create<MyViewModel, Unit>(this.openDrive);
}
private Unit openDrive(MyViewModel viewModel)
{
// Do stuff
return Unit.Default;
}
So setting 'Unit' as the return type of the command, does not get rid of this warning. Does anybody know how to get rid of this warning?
I also would like to ask if if someone knows what would be wrong with my DataTrigger. It emits the same warning as the EventTriggerBehavior, only then with DataTriggerBehavior as type, and it doesn't do anything at all. The image source is supposed to differ per directory entry type, but instead nothing is shown now.
<Image Height="19" Margin="0 0 5 0" Name="image">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding Type}" ComparisonCondition="Equal" Value="{x:Static models:DirectoryEntryType.Directory}">
<ia:ChangePropertyAction TargetObject="{Binding #image}" PropertyName="Source" Value="/Assets/Icons/folder_closed.ico"/>
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding Type}" ComparisonCondition="Equal" Value="{x:Static models:DirectoryEntryType.File}">
<ia:ChangePropertyAction TargetObject="{Binding #image}" PropertyName="Source" Value="/Assets/Icons/cpp.ico"/>
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Image>
I just upgraded my project to latest preview of 0.9 and now its completely broken.
Avalonia.Xaml.Behaviors has started giving stack overflow exceptions. It was working very well with Avalonia 0.8.3 stable.
To reproduce follow below mentioned steps.
Hi,
I'm getting the error "Unable to resolve type Interaction from namespace using:Avalonia.Xaml.Interactivity Line 1, position 2".
I installed the package Avalonia.Xaml.Behaviors
V0.10.0 and this is my code below in my MainWindowView.axaml file:
<Window x:Class="NickvisionMoney.Views.MainWindowView"
xmlns="https://github.com/avaloniaui"
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:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
mc:Ignorable="d" Name="Window" Title="{Binding Title}" Icon="/Assets/icon.ico"
Width="800" Height="600" FontFamily="Segoe UI" WindowState="Maximized">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="Closing" SourceObject="{Binding ElementName=Window}">
<ia:InvokeCommandAction Command="{Binding ExitCommand}"/>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
If i try to build the program with this file open I get this error and my designer claims invalid markup. However, if i close this file in visual studio and build the project then I get no errors and the program runs successfully. I wouldn't mind doing this, but the annoyance is the designer not working and having to close this file every time before building and running. Any ideas what's going on?
Hello,
I'm having an issue with an event of type CellPointerPressed here:
<DataGrid SelectedItem="{Binding SelectedBgmEntry, Mode=TwoWay}" Items="{Binding Items, Mode=OneWay}">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="CellPointerPressed">
<ia:InvokeCommandAction Command="{Binding ActionReorderBgm}"/>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
[...]
</DataGrid>
which always invoke a null DataGridCellPointerPressedEventArgs
ActionReorderBgm = ReactiveCommand.Create<DataGridCellPointerPressedEventArgs>(ReorderBgm);
Here 'e' is always null:
public async void ReorderBgm(DataGridCellPointerPressedEventArgs e) {
if (e == null || e.Column.DisplayIndex != 0)
return;
}
This same code works fine in version 0.10.11-rc.1, it only started since 0.10.11.
Was there a breaking change of some sort in between?
Thanks!
Describe the bug
When using the ListBox control in an Avalonia MVVM application, it appears that the control is firing the SelectionChanged event before updating the SelectedItem property. This results in the SelectedItem property referencing the old value instead of the newly selected item. This is only happening when using EventTriggerBehavior, and the issue does not occur when handling the event in code-behind.
To Reproduce
`<ListBox x:Name="ExampleListBox"
Items="{Binding ExampleItems, Mode=OneWay}"
SelectionMode="Single"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<Interaction.Behaviors>
<EventTriggerBehavior SourceObject="ExampleListBox"
EventName="SelectionChanged">
<InvokeCommandAction Command="{Binding SelectedItemChangedCommand}" />
</EventTriggerBehavior>
</Interaction.Behaviors>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>`
` public ObservableCollection<string> ExampleItems { get; set; } = new()
{
"Test 1",
"Test 2",
"Test 3"
};
[ObservableProperty] private string _selectedExampleItem;
[RelayCommand]
private void SelectedExampleItemChanged()
{
Console.WriteLine(SelectedExampleItem);
}
Expected behavior
The the SelectedItem property should be the item in the ListBox control which has just been selected, rather than the item it was prior to the selection change.
Desktop
Additional context
This may be a similar issue to that being reported here.
I'm on version 0.9.12 of everything. I'm trying to do the following:
<Button Name="GetCalendarsButton" Grid.Column="1" Height="25" Content="Get Calendars" Command="{Binding GetCalendars}" Margin="5">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding FlashGetCalendarsButton}" ComparisonCondition="Equal" Value="true">
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="BorderBrush" Value="Blue"/>
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="BorderThickness" Value="2"/>
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding FlashGetCalendarsButton}" ComparisonCondition="Equal" Value="false">
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="BorderBrush" Value="Transparent"/>
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="BorderThickness" Value="0"/>
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Button>
That doesn't seem to work, but - as an alternate test, this does work:
<Button Name="GetCalendarsButton" Grid.Column="1" Height="25" Content="Get Calendars" Command="{Binding GetCalendars}" Margin="5">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding FlashGetCalendarsButton}" ComparisonCondition="Equal" Value="true">
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="Content" Value="Get"/>
</ia:DataTriggerBehavior>
<ia:DataTriggerBehavior Binding="{Binding FlashGetCalendarsButton}" ComparisonCondition="Equal" Value="false">
<ia:ChangePropertyAction TargetObject="{Binding #GetCalendarsButton}" PropertyName="Content" Value="Get Calendars"/>
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Button>
I tried binding the DataTriggerBehavior's Binding property to the Button's i:VisualStateHelper.Background attached property, but I got an exception:
System.ArgumentException: "Could not find binding source: either target or anchor must be an IStyledElement."
How to change the code?
<Style Selector="Button:pointerover">
<Setter Property="(ia:Interaction.Behaviors)">
<ia:BehaviorCollectionTemplate>
<ia:BehaviorCollection>
<iac:DataTriggerBehavior Binding="{Binding $parent[Button].(i:VisualStateHelper.Background)}"
ComparisonCondition="NotEqual"
Value="{x:Null}">
<iac:ChangePropertyAction TargetObject="$parent"
PropertyName="(i:VisualStateHelper.Background)"
Value="{Binding $parent[Button].(local:ButtonHelper.HoverBackground)}" />
</iac:DataTriggerBehavior>
</ia:BehaviorCollection>
</ia:BehaviorCollectionTemplate>
</Setter>
</Style>
Seems like the ChangePropertyAction does not trigger on initial binding, only after the value changes.
Is there are away of controlling the behaviour?
We are trying to replace DataTriggers from WPF and those run on initial binding as well
DataTriggerBehavior currently executes actions when specific condition is executed as true, as expected.
But DataTriggerBehavior does not execute anything when it was attached and initial condition is true as well.
Consider example below. Trigger should execute actions when binding results in value 50. But if 50 is a default value, trigger won't see that, until you change value to 55 and then back to 50.
<UserControl x:Class="BehaviorsTestApplication.Views.Pages.DataTriggerBehaviorView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:BehaviorsTestApplication.ViewModels"
x:CompileBindings="True" x:DataType="vm:MainWindowViewModel"
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="450">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid RowDefinitions="*,Auto">
<Rectangle Name="DataTriggerRectangle"
Grid.Row="0" Margin="5"
Fill="{DynamicResource BlueBrush}"
Stroke="{DynamicResource GrayBrush}"
StrokeThickness="5">
<i:Interaction.Behaviors>
<ia:DataTriggerBehavior Binding="{Binding #Slider.Value}"
ComparisonCondition="Equal"
Value="50">
<ia:ChangePropertyAction TargetObject="{Binding #DataTriggerRectangle}"
PropertyName="Fill"
Value="{DynamicResource YellowBrush}" />
</ia:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Rectangle>
<StackPanel Grid.Row="1"
Margin="5,0,5,5"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="{Binding #Slider.Value}"
VerticalAlignment="Center"
Width="50"
Foreground="{DynamicResource GrayBrush}" />
<Slider Name="Slider" Value="50" Width="400" IsSnapToTickEnabled="True" TickFrequency="1" />
</StackPanel>
</Grid>
</UserControl>
not sure what is correct behavior.
Hello
I have Grid
on Window
, and i try to add Behavior for DragOver
and Drop
event's, witch will call my custom ReactiveCommand
in MyViewModel
.
<Grid DragDrop.AllowDrop="True">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="Drop">
<ia:InvokeCommandAction Command="{Binding DropCommand}" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</Grid>
But i get a System.Xaml.XamlException: Cannot find an event named Drop on type Grid.
So i try to find else way to solve it, i found some DragDrop parameter and try to add command here DragDrop.Drop="DropCommand"
, and I see the following exception System.Xaml.XamlException: "Unable to resolve suitable regular or attached property Drop on type Avalonia.Input:Avalonia.Input.DragDrop
.
Is it's a bug? Couse a Grid
definitely has this event's.
And if i am do something wrong, please tell me how i can add a ReactiveCommand
to Drop and DragOver events, which will called after event was invoked?
When launching the sample app I get an IvalidOperationException in BehaviorsTestApplication.Controls.CallMethodActionControl on the TargteObject Binding of the first CallMethodAction. It says "AvaloniaValue.UnsetValue is not a valid value for BindingValue<>."
try to bind like in your sample
<ListBox x:Name="listBox" Grid.Row="3" Grid.Column="1" Items="{Binding Collection}"
SelectedItem="{Binding ShowObject}" >
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="DoubleTapped" SourceObject="{Binding #listBox}">
<ia:InvokeCommandAction Command="{Binding EnterClickCommand}" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Bitmap}" MaxHeight="25" MaxWidth="25" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
but have an exception in debug output
[Binding] Error in binding to "Avalonia.Xaml.Interactions.Core.InvokeCommandAction"."Command": "Null value in expression ''." (Avalonia.Xaml.Interactions.Core.InvokeCommandAction #63183526)
use Avalonia 0.8.999
use behaviors 0.9.0
Currently, ContentDragBehavior
will forward only the binded Context
into the drag+drop interaction. IDragHandler.BeforeDragDrop
does not seem to allow for a produced value to be specified as the drag+drop payload.
Use case: I have an image editor where I make selections and drag+drop to replace contents. There is no backing collection and as such it doesn't work like a collection control. The source Context
is the VM because there is logic that I want to run before drag initiated.
I want to produce the payload (an object with copied image data and/or tile metadata) at drag initiation because it's expensive to repeatedly create during selection. I also want the drag+drop interaction to "own" the payload at that point so that the source VM doesn't need to. I have already done this locally by extending IDragHandler
and creating a modified ContextDragBehavior
, though this is probably not an appropriate API for the library if you can break IDragHandler.BeforeDragDrop
.
My local changes:
public interface IDragHandlerEx : IDragHandler
{
public object? Payload { get; set; }
}
I have modified ContextDragBehavior
to use IDragHandlerEx
and this area of ContextDragBehavior to:
var context = Context ?? AssociatedObject?.DataContext;
Handler?.BeforeDragDrop(sender, _triggerEvent, context);
var payload = Handler?.Payload ?? context;
await DoDragDrop(_triggerEvent, payload);
Handler?.AfterDragDrop(sender, _triggerEvent, context); // This may need payload as an extra parameter
Hi. Thank you for this amazing library. Following Drag and drop example, I manged to full integrate reordering of rows in DataGrid control. However what is lacking is the clear position of the dragged element and where will it be dropped. When you drag a row in the DataGrid, how can I style it so that there is an drop effect within the grid itself which will show me where the element will be positioned, between to rows.
Thanks
Not sure if it is a avalonia or behavior Problem. I have following behavior:
public class DoubleTappedBehavior : Behavior<TreeViewItem>
{
public static readonly AttachedProperty<ICommand> CommandProperty =
AvaloniaProperty.RegisterAttached<DoubleTappedBehavior, TreeViewItem, ICommand>("Command", null, false, defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
public static ICommand GetCommand(TreeViewItem element)
{
return element.GetValue(CommandProperty);
}
public static void SetCommand(TreeViewItem element, string value)
{
element.SetValue(CommandProperty, value);
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.DoubleTapped += DoubleTapped;
}
protected override void OnDetaching()
{
AssociatedObject.DoubleTapped -= DoubleTapped;
base.OnDetaching();
}
private void DoubleTapped(object sender, RoutedEventArgs e)
{
if (Command == null)
return;
Command.Execute(null);
}
}
I use it this way:
<TreeView.Styles>
<Style Selector="TreeViewItem">
<Setter Property="commandBehaviors:DoubleTappedBehavior.Command"
Value="{Binding Command}"/>
</Style>
</TreeView.Styles>
</TreeView>
The Get/Set Command is never get called. Also the attached method. Not sure where the problem is.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.