C
C#14mo ago
Philip

✅ Working on a WPF Project, how can I get what StackPanel is selected?

Working on a WPF Project, how can I get what StackPanel is selected by the user and save it to use it in my class?
<Style TargetType="ListViewItem">
<Setter Property="Cursor" Value="Hand"/>

<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal" Margin="4" MinHeight="25" Background="{TemplateBinding Background}">
<Image Width="34" RenderOptions.BitmapScalingMode="Fant" Source="{Binding Image}"/>
<TextBlock Text="{Binding Country}" Margin="4,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>

<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ListViewItem">
<Setter Property="Cursor" Value="Hand"/>

<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal" Margin="4" MinHeight="25" Background="{TemplateBinding Background}">
<Image Width="34" RenderOptions.BitmapScalingMode="Fant" Source="{Binding Image}"/>
<TextBlock Text="{Binding Country}" Margin="4,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>

<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
</Style.Triggers>
</Style>
79 Replies
Philip
PhilipOP14mo ago
I want to implement it here:
public ProtectionViewModel()
{
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}

ConnectCommand = new RelayCommand(o =>
{

ConnectionStatus = "Connecting...";
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files\OpenVPN\bin\openvpn.exe";
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
ConnectionStatus = "Connected";

});
}
public ProtectionViewModel()
{
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}

ConnectCommand = new RelayCommand(o =>
{

ConnectionStatus = "Connecting...";
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files\OpenVPN\bin\openvpn.exe";
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
ConnectionStatus = "Connected";

});
}
Please let me know, if you need more information.
Pobiega
Pobiega14mo ago
Selected? Panels don't have a "selected" mode. Did you mean focused?
Philip
PhilipOP14mo ago
StackPanels in Xaml I put the wrong code in the first one, my bad.
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
Pobiega
Pobiega14mo ago
there is no IsSelected property on a stack panel I don't know how else I can put this. They can't be selected. They are not selectable. Did you mean IsFocused?
Philip
PhilipOP14mo ago
Uhm, maybe I'm calling it the wrong thing 😅 When I click on it, it says selected With this code
Pobiega
Pobiega14mo ago
Ah, I see you have a ListView with each row being populated with a stack its the ListViewItem that has the IsSelected property not the panel itself
Philip
PhilipOP14mo ago
Ah, okay. Can I somehow track which Item is selected and use it in my function?
Pobiega
Pobiega14mo ago
absolutely
Philip
PhilipOP14mo ago
Awesome! Mind helping me a little? 😅
Pobiega
Pobiega14mo ago
you're using MVVM, so just bind the SelectedItem property on the list itself
Philip
PhilipOP14mo ago
I'm kinda lost when it comes to C#... 😅 Mostly followed a tutorial to come to where I'm at on this project and I roughly understand what I'm doing. I know how to bind it, so I can change the value of the element but not the otherway around. 😅 Do you maybe mind helping? :)
Pobiega
Pobiega14mo ago
Well, you know how to bind it, so do that first
Philip
PhilipOP14mo ago
The value, right?
Pobiega
Pobiega14mo ago
I obviously don't mind helping, as I already am helping? 😛 what value? SelectedItem on your listview
Philip
PhilipOP14mo ago
Totally lost, I would not be binding the value of IsSelected?
No description
Pobiega
Pobiega14mo ago
wh.. what are you doing? Those are not MVVM bindings
Philip
PhilipOP14mo ago
Good question 😂 Where am I doing that? 😭
No description
Pobiega
Pobiega14mo ago
well, first you make a property in your viewmodel that will hold the bound value SelectedItem on ListView is of type object, so you might need the binding to also be object ?
Philip
PhilipOP14mo ago
in ProtectionViewModel.cs
No description
Philip
PhilipOP14mo ago
Correct?
Pobiega
Pobiega14mo ago
string is not correct
Philip
PhilipOP14mo ago
bool?
Pobiega
Pobiega14mo ago
object
MODiX
MODiX14mo ago
Pobiega
SelectedItem on ListView is of type object, so you might need the binding to also be object
React with ❌ to remove this embed.
Philip
PhilipOP14mo ago
Never worked with an object? Is it for true or false? or?
Pobiega
Pobiega14mo ago
... what the fuck is this your first day of C#? what are you doing making WPF apps
Philip
PhilipOP14mo ago
Good question.
Pobiega
Pobiega14mo ago
WPF with MVVM isn't really beginner level topics lol
Philip
PhilipOP14mo ago
Yeah I kinda figured out 😂 Well. I have the object now.
Philip
PhilipOP14mo ago
No description
Philip
PhilipOP14mo ago
I've used it for WinForms a lot before, but never made any console apps etc.
Pobiega
Pobiega14mo ago
okay, now you need to set up a binding <ListView SelectedItem="{Binding SelectedItem}">
Philip
PhilipOP14mo ago
Am I stupid or is it now how my code is formatted?
<Style TargetType="ListViewItem">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal" Margin="4" MinHeight="25" Background="{TemplateBinding Background}">
<Image Width="34" RenderOptions.BitmapScalingMode="Fant" Source="{Binding Image}"/>
<TextBlock Text="{Binding Country}" Margin="4,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ListViewItem">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal" Margin="4" MinHeight="25" Background="{TemplateBinding Background}">
<Image Width="34" RenderOptions.BitmapScalingMode="Fant" Source="{Binding Image}"/>
<TextBlock Text="{Binding Country}" Margin="4,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#1E1E1E"/>
</Trigger>
</Style.Triggers>
</Style>
Philip
PhilipOP14mo ago
Also this would be needed, right?
No description
Pobiega
Pobiega14mo ago
not really thats only if you need a two-way binding
Philip
PhilipOP14mo ago
Oh well 😅
Pobiega
Pobiega14mo ago
I assume you dont actually want to force set items in the view
Philip
PhilipOP14mo ago
Yeah, correct.
Pobiega
Pobiega14mo ago
so if you just want to know whats selected, a one way is fine
Philip
PhilipOP14mo ago
Alright.
Pobiega
Pobiega14mo ago
you keep showing your style I dont care about your style where is your ACTUAL xaml?
Philip
PhilipOP14mo ago
Ahh
Pobiega
Pobiega14mo ago
here is mine
<Button Command="{Binding ShowSelectedItemCommand}">Click me</Button>

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
</ListView>
<Button Command="{Binding ShowSelectedItemCommand}">Click me</Button>

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
</ListView>
and here is my viewmodel
Philip
PhilipOP14mo ago
There we go
Pobiega
Pobiega14mo ago
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<string> items = new ObservableCollection<string>()
{
"hello",
"there"
};

[ObservableProperty]
private object? selectedItem;

[RelayCommand]
private void ShowSelectedItem()
{
MessageBox.Show(SelectedItem?.ToString() ?? "nothing");
}
}
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<string> items = new ObservableCollection<string>()
{
"hello",
"there"
};

[ObservableProperty]
private object? selectedItem;

[RelayCommand]
private void ShowSelectedItem()
{
MessageBox.Show(SelectedItem?.ToString() ?? "nothing");
}
}
Philip
PhilipOP14mo ago
No description
Pobiega
Pobiega14mo ago
note that I'm using a helper package to not have to write the annoying parts 😄 that what the attributes do for me
Philip
PhilipOP14mo ago
Alright
Philip
PhilipOP14mo ago
No description
Pobiega
Pobiega14mo ago
oh okay, you're actually using a proper ItemSource nice
Philip
PhilipOP14mo ago
Yeah 👍 I know what that means. ;)
Pobiega
Pobiega14mo ago
so the SelectedItem property is now actually populated by your ServerModel instance that is the source for your row from here
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}
Philip
PhilipOP14mo ago
So I would need a variable in here?
Philip
PhilipOP14mo ago
No description
Pobiega
Pobiega14mo ago
for what?
Philip
PhilipOP14mo ago
Nvm 😅
Pobiega
Pobiega14mo ago
you have access to all the data in there already
Philip
PhilipOP14mo ago
Okay
Pobiega
Pobiega14mo ago
for the selected row
Philip
PhilipOP14mo ago
Ah okay So I can use the Binding from inside the Server Model now?
Pobiega
Pobiega14mo ago
yes, its the SelectedItem property I'd set it to object? btw since technically nothing might be selected You could even add a helper property now public ServerModel? SelectedServerModel => (ServerModel?)SelectedItem; that way you don't need to cast SelectedItem
Philip
PhilipOP14mo ago
Uhm I'm completely lost again 😂 How do I implement it now?
public ProtectionViewModel()
{
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}

ConnectCommand = new RelayCommand(o =>
{

ConnectionStatus = "Connecting...";
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files\OpenVPN\bin\openvpn.exe";
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
ConnectionStatus = "Connected";
ShowSelectedItem();

});
}
public ProtectionViewModel()
{
Servers = new ObservableCollection<ServerModel>();
{
Servers.Add(new ServerModel
{
Country = "Germany",
Image = "https://tse2.mm.bing.net/th?id=OIP.xp_gP4N6JVcGfHcGVr7acgHaD6",
Config = "--config ./VPN/de-udp6.ovpn"
});
Servers.Add(new ServerModel
{
Country = "United States",
Image = "https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/2560px-Flag_of_the_United_States.svg.png",
Config = "--config ./VPN/us-udp6.ovpn"
});
}

ConnectCommand = new RelayCommand(o =>
{

ConnectionStatus = "Connecting...";
var process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files\OpenVPN\bin\openvpn.exe";
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
ConnectionStatus = "Connected";
ShowSelectedItem();

});
}
I want it to check which country is selected and then change the
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
startInfo.Arguments = "--config ./VPN/de-udp6.ovpn";
dependent on the Item selected. This right?
Philip
PhilipOP14mo ago
No description
Pobiega
Pobiega14mo ago
I'm so confused
Philip
PhilipOP14mo ago
Me included. 😅
Pobiega
Pobiega14mo ago
you are sharing only snippets and tiny screenshots of parts of your code its a nightmare to work like that
Philip
PhilipOP14mo ago
Sure I can share the whole thing.
Pobiega
Pobiega14mo ago
or just, y'know, do what I say public string? SelectedServerModel => (string?)SelectedItem; add that to your viewmodel err not with string, but ServerModel then when you want to check what config is selected, you try to access SelectedServerModel and check that its not null, and then access the .Config property on the servermodel
Philip
PhilipOP14mo ago
Easier said than done... 😅 Can I share the whole project in an easy way?
Pobiega
Pobiega14mo ago
$paste
MODiX
MODiX14mo ago
If your code is too long, you can post to https://paste.mod.gg/ and copy the link into chat for others to see your shared code!
Pobiega
Pobiega14mo ago
but honestly, all the hard parts are done you just need to add a property and access it thats literally it
Philip
PhilipOP14mo ago
BlazeBin - mpuspbgpqkrn
A tool for sharing your source code with the world!
Philip
PhilipOP14mo ago
Where is this supposed to go?
Pobiega
Pobiega14mo ago
in your viewmodel
Philip
PhilipOP14mo ago
But it still doesn't show the selected item... 🤔 It's still this.
Pobiega
Pobiega14mo ago
I have maybe 5 minutes available. Can you screenshare and we just fix this super fast, and then you promise me to stop doing WPF and learn C# before resuming?
Philip
PhilipOP14mo ago
Sorry, Still available? Promise you this is toture for me 😂
Pobiega
Pobiega14mo ago
#dev-vc-1
Want results from more Discord servers?
Add your server