frostfina
frostfina
CC#
Created by frostfina on 1/28/2023 in #help
❔ Generic method that takes in a struct and calls the correctly-typed method
I'm working with OpenTK (an OpenGL binding) and I'd like to create a method that allows setting uniforms (basically variables inside of a shader). The solution I've come up with is the following. For context, Matrix4 is a struct. This method is part of my Shader class, in which I'm trying to abstract the native types.
public void SetUniform<T>(string name, T value) where T : struct
{
if (typeof(T) == typeof(Matrix4))
{
GL.UniformMatrix4(_uniforms[name], false, (Matrix4)value);
}
}
public void SetUniform<T>(string name, T value) where T : struct
{
if (typeof(T) == typeof(Matrix4))
{
GL.UniformMatrix4(_uniforms[name], false, (Matrix4)value);
}
}
The cast (Matrix4)value doesn't work though. I wrote it like this so that I can write a single method to set any type of uniform value, here the only implemented one is Matrix4. My question is : Is there a way to make this work, or do I have to write a method for each type of argument? If that's a bad solution, what would be a good one? (Alternatively, I could abstract uniforms further with an Uniform class so I'm not directly working with the native types in my shader abstraction, but that would also require adding an abstraction for the uniform use cases.)
20 replies
CC#
Created by frostfina on 11/2/2022 in #help
Passing a string property to a command via a button CommandParameter in .NET 6
Hello So I'm trying to pass a string (that's bound to a text field via a data context <TextBox [...] Text="{Binding SearchString}"/> which I made sure already works) using a button's CommandParameter. The relevant button code is as follows (I've hidden layout arguments)
<Button [...] Command="{Binding PerformSearch}" CommandParameter="{Binding SearchString}" />
<Button [...] Command="{Binding PerformSearch}" CommandParameter="{Binding SearchString}" />
PerformSearch is a property of the class MainViewModel that I have defined as a custom class
internal class SearchCommand : ICommand
{
public event EventHandler? CanExecuteChanged;

public bool CanExecute(object? parameter)
{
System.Diagnostics.Debug.WriteLine("CanExecute(parameter) : parameter=" + parameter);
return true;
}

public void Execute(object? parameter)
{
System.Diagnostics.Debug.WriteLine("Execute(parameter) : parameter=" + parameter);
}
}
//...
internal class MainViewModel : INotifyPropertyChanged
{
// ...
public ICommand? PerformSearch { get; } = new SearchCommand();
// ...
}
internal class SearchCommand : ICommand
{
public event EventHandler? CanExecuteChanged;

public bool CanExecute(object? parameter)
{
System.Diagnostics.Debug.WriteLine("CanExecute(parameter) : parameter=" + parameter);
return true;
}

public void Execute(object? parameter)
{
System.Diagnostics.Debug.WriteLine("Execute(parameter) : parameter=" + parameter);
}
}
//...
internal class MainViewModel : INotifyPropertyChanged
{
// ...
public ICommand? PerformSearch { get; } = new SearchCommand();
// ...
}
This does however not work, pressing the button does call the command and I do see
CanExecute(parameter) : parameter=
Execute(parameter) : parameter=
CanExecute(parameter) : parameter=
Execute(parameter) : parameter=
in the program's output, however after testing parameter is null. If I pass a string directly instead of using a binding, I do get the string as an output
<Button [...] Command="{Binding PerformSearch}" CommandParameter="Hello" />
<Button [...] Command="{Binding PerformSearch}" CommandParameter="Hello" />
which produces
CanExecute(parameter) : parameter=Hello
Execute(parameter) : parameter=Hello
CanExecute(parameter) : parameter=Hello
Execute(parameter) : parameter=Hello
What am I doing wrong with my previous binding? Maybe this is the wrong way of handling button presses? I've seen people just use CommandParameter="Binding" and pass the whole ViewModel, and it does indeed pass the whole viewmodel, but I feel like it defeats the purpose of having a separate class handle the command.
28 replies