|
I've implemented "tree views" using a user control "around" a ListView. All my user control revolve around something; nothing ever so special that it required a "custom control" (which is more complicated).
For a tree view - list view, each item is a usercontrol that can "indent" or "hide" itself (when expanding or collapsing). The item's user control has it's own data template; and that's how you can have every every item (level) look different by selectively exposing different parts of the same UC type.
All that's required of the item "data container" is a level number and an "expanded / collapsed" indicator; the level number is used to compute the indent (a Margin or some other "empty" object with length). The items are of course loaded in the proper sequence (hierarchy / BOM). A selection change handler can identify what level and "node" is being accessed. An expand / collapsed method keys off the current selected item and just travels the sequence below that depth.
I also added parent and child pointers (based on my needs). And added drag and drop from the (listview) tree view. On the surface, you can't tell it's a listview. Once you build one, only the item data template changes for the next "tree view".
The "drop down" could be the tree view inside a ScrollViewer, inside an Expander. Or a popup. What ever works best.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
As the title says, I am facing an issue when the styles of a window element are coming from an external resource dictionary which is included into a .dll reference of my project. The problem is that styles aren't apply in design mode!!!
To be more specific...
I have create a (.NET 4.8 Framework) WPF control library project which, among other stuff, includes some resource dictionary (.xaml) files with styles. To use these styles into a (.NET 4.8 Framework) WPF application project, as far as I know, I can use two ways...
WAY ONE: ( [^]Example )
■ Into the solutions of my application project I add my control library as a new project.
■ I go into my application project and I add a reference that points to my control library project (.csproj) file.
■ I add the .xaml file from my control library project into the App.xaml file of my application project as merged dictionary.
■ And finally, I give the desired style to my window element.
Using way one it works fine, in design mode too, but what if, for various obvious reasons, I want to give my control library to someone as a .dll file? Then, as far as I know, I have to use the second way...
WAY TWO: ( [^]Example )
■ Without to add my control library as a new project into the solution of my application project, I go to my application project and I add a reference that points to the .dll file of my control library.
■ I add the .xaml file from my control library project into the App.xaml file of my application project as merged dictionary.
■ And finally, I give the desired style to my window element.
But, using way two, styles are applying only when I run the program and not in design mode!!! And this happens only for window elements!!! As you can see if you run the code of "Way Two" example, the grid gets the given style even in design mode. The problem is with the window element!!!
I made this question in Stackoverflow too and I got [^]this answer which doesn't work for me. [^]Here is an example code I tried based on above answer...
I also made the same question here, in Quick Answers section and I got [^]this answer which also doesn't work for me. [^]Here is an example code I tried based on above answer.
In both cases I still have the same problem. The styles of the window element are not applied in design mode!!!
Can someone help me to solve this issue please?
PS: I am working on Window 10 machine, using Visual Studio 2022 version 17.5.0 and my WPF projects based on .NET 4.8 Framework.
Thank you for your time!!!
|
|
|
|
|
|
@Graeme_Grand [^] who wrote this [^] and then he deleted it!!!
/////
Normally I wouldn't go into this process but after this arrogant irony "I don't think that it is so much as the solution does not work, but who is using it" I will.
Υour solution doesn't work for me because into your examples you load the library as .csproj and not as .dll file. You can download [^]this (.NET Framework 4.8) project so to see what I mean. Or you can recreate the whole thing by your self using .NET Framework 4.8 and loading the library as .dll file. And not as a project.
If you make it work that way I will humbly apologize, otherwise you will have to. Of course you can just ignore me. The only thing that isn't accepted is the irony and the arrogance... This kind of behavior is shameful to anyone!!!
modified 24-Feb-23 5:57am.
|
|
|
|
|
@Graeme_Grand [^]
/////
Oh, I missed the point... And it won't work... Well I have some "bad news". After some tests, it is working, in a way!!! Both, in design time and run time too. Even if I reference my library as .dll to a separate project. But, for some reason that I can't understand for now (since I'm new to WPF) I had to change the target type of <Style x:Key="MainWindow_Style" TargetType="{x:Type Window}"> from Window to Control . Of course I can't use it like this because I'll loose the ability to style properties of Window element. So what I am trying to find right now is "why is this happening?". Why this issue is happening only with Window element?
modified 24-Feb-23 7:51am.
|
|
|
|
|
@Graeme_Grand [^]
/////
Yes, I have a 100% working solution right now and I'll post it as soon as I get back the reputation points that were taken away from me for daring to be right!!!
PS: Some people in here need a psychiatric follow-up. Frankly...
modified 24-Feb-23 7:52am.
|
|
|
|
|
I'm trying to create a simple log in window. The Sign In button does not get enabled. The CanExecuteChange fires on startup, but never after that.
You can see that I'm using the Community Toolkit. I've also tried the RelayCommand in my own framework. Neither work. I have also tried
CommandManager.InvalidateRequerySuggested();
in the UserName and Password properties.
Here's the Sign In button
<Button Grid.Row="7"
Grid.Column="0"
Content="Sign In"
Command="{Binding SignInCommand}"
Margin="0,0,0,0"/>
Here's the View Model
using CommunityToolkit.Mvvm.Input;
using Marois.Framework.Core.Shared;
using System.Windows.Input;
namespace Jayhawk.UI.WPF.ViewModels
{
public class LoginViewModel : _DialogViewModelBase
{
#region Private Fields
private readonly IEventAggregator _eventAggregator;
#endregion
#region Properties
private string? _UserName;
public string? UserName
{
get { return _UserName; }
set
{
SetProperty(nameof(UserName), ref _UserName, value);
}
}
private string? _Password;
public string? Password
{
get { return _Password; }
set
{
SetProperty(nameof(Password), ref _Password, value);
}
}
private bool _IsRememberMeChecked;
public bool IsRememberMeChecked
{
get { return _IsRememberMeChecked; }
set
{
SetProperty(nameof(IsRememberMeChecked), ref _IsRememberMeChecked, value);
}
}
private bool _IsLoggingIn;
public bool IsLoggingIn
{
get { return _IsLoggingIn; }
set
{
SetProperty(nameof(IsLoggingIn), ref _IsLoggingIn, value);
}
}
#endregion
#region Commands
private ICommand? _SignInCommand;
public ICommand? SignInCommand
{
get
{
if (_SignInCommand == null)
_SignInCommand = new RelayCommand(SignInExecuted, SignInCanExecute);
return _SignInCommand;
}
}
#endregion
#region CTOR
public LoginViewModel()
{
}
#endregion
#region Private Methods
private bool SignInCanExecute()
{
return !string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password);
}
private void SignInExecuted()
{
IsLoggingIn = true;
}
#endregion
}
}
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Looking at the source code for CommunityToolkit.Mvvm.Input.RelayCommand [^], it doesn't use the CommandManager at all. You need to explicitly call the NotifyCanExecuteChanged method[^] instead.
NB: That SetProperty method looks odd - any relatively recent framework would use [CallerMemberName] so that you don't need to pass the name of the property:
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
public string? UserName
{
get { return _UserName; }
set { SetProperty(ref _UserName, value); }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
hi guys, how to set the icon for output result(.exe) in vs2022 ? thanks.
|
|
|
|
|
Try Project -> Properties.
|
|
|
|
|
|
I'm trying to create a ListBox, with it's ItemTemplate being an expander, which itself has a list in it.
Here's a pic of what I'm trying to accomplish. Pic
I added colors around each item to highlight what's happening.
Here's the XAML
<ListBox Grid.Row="2"
Grid.Column="1"
x:Name="outerList"
Margin="2,2,2,2"
Background="Transparent"
ItemsSource="{Binding RecentItemSections}"
SelectedItem="{Binding SelectedRecentItemSection}"
HorizontalAlignment="Stretch"
BorderBrush="Yellow"
BorderThickness="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="{Binding IsSectionExpanded}"
x:Name="expander"
HorizontalAlignment="Stretch"
BorderBrush="Red"
BorderThickness="2">
<Expander.Header>
<TextBlock Text="{Binding SectionName}"
Foreground="White"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}, Path=ActualWidth}"/>
</Expander.Header>
<ListBox ItemsSource="{Binding RecentItems}"
BorderBrush="Green"
BorderThickness="5"
Margin="2,0,20,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="MediumAquamarine"
BorderThickness="2">
<StackPanel Orientation="Vertical"
HorizontalAlignment="Stretch">
<TextBlock Text="{Binding ItemName}"
FontSize="12"
Margin="2"/>
<TextBlock Text="{Binding ItemLocation}"
FontSize="10"
Margin="2,0,2,2"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As you can see in the pic, the Expander's header is off the right side of the listbox item.
How can I get the expander to fit inside its parent, the ListBox?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You should know what the maximum header width will be; set the .Width accordingly. (The framework doesn't know beforehand).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I'd like to load a TabItems's content async.
What would be nice is to see the Tab Item added to the TabControl, then do the async load while a spinning indicator is running.
Something like ContentRendered would do, but I don't see anything like it on the TabItem.
Anyone know of a way to do this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
When I do this type of thing, I use MVVM and have a state represent the loaded nature; the visibility of the spinner animation is bound to the loaded state.
|
|
|
|
|
Let me clarify my question... I'm not asking about the indicator...
- Tab appears.
- Spinning indicator appears
- Call GetData
- Data is returned
- Tab's content is loaded
- Indicator goes away.
The problem is that I want to show a blank tab first, then start the process of getting the data. But where do you start it from? There doesn't seem to be a ContentRedered or Loaded or Initialized event to kick off the async data call after the tab is visible
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I can't tell whether you are using MVVM or not from your question. If I were doing this, I would adopt a slightly different approach; I would bind the tabs to an ObservableCollection. When I instantiate my new tab and add it to the collection, I would trigger the async load. In other words, I disconnect the state from the visual. I don't need to worry about tracking tab states because this is automatically connected to my ViewModel.
|
|
|
|
|
TabItem inherits from FrameworkElement and therefore has a "Loaded" event.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
When you design a CustomControl or UserControl, how do you fire off a method inside it?
Say for example you create a control that needs to load some data async. So you put the control on a Window and start the window. There's no way to call into the control and call 'Load()'.
You can bind to it, but what would you bind? You could have it listen to an event. Is there some other way?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 31-Dec-22 14:45pm.
|
|
|
|
|
You can use async but you may be on a different thread to the UI when trying to update data bound to the UI. You need to marshall to the UI thread or you will get cross-thread exceptions. My previous answer where I point to a series of WPF YT videos will answer this question for you.
Graeme
"I fear not the man who has practiced ten thousand kicks one time, but I fear the man that has practiced one kick ten thousand times!" - Bruce Lee
|
|
|
|
|
Not sure what you mean by this response.
I'm asking how to create a UserControl or CustomControl, place it on a Window, then execute a method on it from a button click on the Window.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Kevin Marois wrote: I'm asking how to create a UserControl or CustomControl, place it on a Window, then execute a method on it from a button click on the Window.
Okay, that is a lot clearer and easier to understand what you want.
I wrote an article that walks through extending a Control: Flexible WPF ToggleSwitch Lookless Control in C# & VB[^]. UserControls are just like another Window to use.
Graeme
"I fear not the man who has practiced ten thousand kicks one time, but I fear the man that has practiced one kick ten thousand times!" - Bruce Lee
|
|
|
|
|
|
I'm not asking about events. I'm asking how to call the Load method on my UserControl from the Window's ViewModel. The UserControl uis a stand along control. It needs to have Load called to load up the data. The Window's ViewModel doesn't know about the UserControl.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You give the user control a .Name in the XAML; the .Name is available to the Window's code behind. If you want to access the UC outside of the Window, you need to add a public reference to the UC; e.g. public Type UC => (name of UC in XAML).
In those cases where the UC is a (global) singleton, I (may) give it a public static reference to its instance; the UC can then be accessed by any part of the app in that case.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|