|
I was going to take a look, but it looks like your repo is private.
|
|
|
|
|
Oops. It's public now.
Thanks Pete!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I'll have a look in the morning.
|
|
|
|
|
Hey Pete, just following up to see if had a chance to look at this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have spent some time digging into your sample and I am at a loss. I can't see anything obvious in there, and it's an absolute stumper.
|
|
|
|
|
The first obvious issue: the ContainerItems property is not a dependency property. As I said, for a DependencyObject -derived class, WPF will only observe property changes for dependency properties.
public static readonly DependencyProperty ContainerItemsProperty
= DependencyProperty.Register("ContainerItems",
typeof(List<NavigationPane>),
typeof(NavigationContainer),
new PropertyMetadata(null));
public List<NavigationPane> ContainerItems
{
get { return (List<NavigationPane>)GetValue(ContainerItemsProperty); }
set { SetValue(ContainerItemsProperty, value); }
}
Next problem: since you're using a List<T> rather than an ObservableCollection<T> , WPF will only notice when you set the property. Since you do that before adding any items to the list, WPF will never notice the panes being loaded. Change the code to set the property after populating the list:
private async Task Load()
{
if (NavigationPanes != null)
{
var items = new List<NavigationPane>();
List<Task> tasks = new List<Task>(NavigationPanes.Count);
foreach (var navigationPaneModel in NavigationPanes)
{
tasks.Add(LoadPane(navigationPaneModel, items));
}
await Task.WhenAll(tasks);
ContainerItems = items;
}
}
private async Task LoadPane(NavigationPaneModel navigationPaneModel, List<NavigationPane> containerItems)
With those changes in place (and dropping the Thread.Sleep values so it loads in a reasonable time), I now get four expanders in the list. However, although they have different headers, none of them contain any data.
Looking in the Generic.xaml file, you're binding the Header property, but not the Items property:
<ctrls:NavigationPane BorderBrush="Yellow"
BorderThickness="1"
Background="Red"
HorizontalAlignment="Stretch"
Header="{Binding Header}"
Margin="0,0,0,1"/> Once you add Items="{Binding Items}" to that, the listboxes are now populated.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
It's working now. Thanks Richard.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Richard, after implementing your changes, the loading works fine, but I now have this problem[^] with the expander headers.
I would appreciate your input.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Is it possible to put this path in a style? I'd like to add a data trigger to change the fill color on mouse over
<Path Grid.Column="0"
x:Name="path"
Width="16"
Height="16"
Data="M19,19H5V5H19M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M13.96,12.29L11.21,15.83L9.25,13.47L6.5,17H17.5L13.96,12.29Z"
Fill="{DynamicResource pathActiveColor}"
Stretch="Uniform"
Margin="4,2,2,2"/>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Since there's "data", it's more a resource (to be styled) than a style.
"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
|
|
|
|
|
This did it. Thanks!
<Window.Resources>
<pre>
<Path x:Key="PathKey"
Width="20"
Height="20"
Data="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z"
Fill="Red"
Stretch="Uniform" />
<Style TargetType="{x:Type Button}">
<Setter Property="Content">
<Setter.Value>
<DynamicResource ResourceKey='PathKey' />
</Setter.Value>
</Setter>
</Style>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 12-Apr-23 12:55pm.
|
|
|
|
|
I typically bind "Fill" or "ForeGround", etc. to an expression in the "view model" (=> ...) if it can vary from one object to the next; I use "styling" only when a group is all styled the same. (Brushes can be shared).
(UWP doesn't have XAML "data triggers" so I stopped thinking about them).
How do you reference a Path stored as a resource?
"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
|
|
|
|
|
Ya, I'm going to. Ultimately it will be in a theme with data trigger to change the color for state, such as Enabled, Disabled, MouseOver, etc.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
FYI, here's what I came up with. Thanks for your help!
Control
public class MaroisPathImageButton : Button
{
#region CTOR
static MaroisPathImageButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MaroisPathImageButton), new FrameworkPropertyMetadata(typeof(MaroisPathImageButton)));
}
#endregion
#region Dependency Properties
#region DP Caption
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption",
typeof(string),
typeof(MaroisPathImageButton),
new PropertyMetadata(""));
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
#endregion
#region DP PathData
public static readonly DependencyProperty PathDataProperty =
DependencyProperty.Register("PathData",
typeof(System.Windows.Media.Geometry),
typeof(MaroisPathImageButton),
new PropertyMetadata(null, new PropertyChangedCallback(OnPathDataChanged)));
public System.Windows.Media.Geometry PathData
{
get { return (System.Windows.Media.Geometry)GetValue(PathDataProperty); }
set { SetValue(PathDataProperty, value); }
}
private static void OnPathDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MaroisPathImageButton control = (MaroisPathImageButton)d;
}
#endregion
#endregion
}
Theme
<!--PATH DATA-->
<Geometry x:Key="toolbarHomeButtonPathData">
M12 5.69L17 10.19V18H15V12H9V18H7V10.19L12 5.69M12 3L2 12H5V20H11V14H13V20H19V12H22
</Geometry>
<!BASE PATH IMAGE BUTTON STYLE>
<Style x:Key="pathImageButtonStyle"
TargetType="{x:Type mctrls:MaroisPathImageButton}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="65"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="Grid">
<Border x:Name="border"
Margin="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
CornerRadius="3">
<StackPanel Orientation="Vertical">
<Path x:Name="path"
Width="20"
Height="20"
Data="{Binding PathData, RelativeSource={RelativeSource TemplatedParent}}"
Fill="{StaticResource Button.Normal.Background}"
Stretch="Uniform"/>
<TextBlock Grid.Row="1"
Grid.Column="0"
x:Name="caption"
Text="{Binding Caption, RelativeSource={RelativeSource TemplatedParent}}"
Foreground="{StaticResource Button.Normal.Background}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,2"/>
</StackPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Normal.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource Button.Hover.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Hover.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!TOOLBAR HOME BUTTON STYLE>
<Style x:Key="toolbarHomeButtonStyle"
BasedOn="{StaticResource pathImageButtonStyle }"
TargetType="{x:Type mctrls:MaroisPathImageButton}">
<Setter Property="Caption" Value="Home"/>
<Setter Property="PathData" Value="{StaticResource toolbarHomeButtonPathData}"/>
</Style>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
|
Something I have used in the past XAML Path Icons[^]. They allow you to download the XAML paths for icons which you can adjust as necessary.
|
|
|
|
|
OK so I got it from the MS Store on my PC. But I don't see it installed. How do I open this each time I want to use the icons?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I normally just type XAML Path Icons in my window search bar. It opens from there for me.
|
|
|
|
|
My company has a product that runs on Windows, Android, and iOS. They want to define the app themes in json files so they can be shared across each app.
The only way I can see this working in Windows is to deserialize the json into a class and apply themes programmatically versus using theme dictionaries.
Anyone have any thoughts on this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 6-Mar-23 13:04pm.
|
|
|
|
|
I'm trying to create a Custom Control that will be a DropDown TreeView.
Basically I want to replace a comboboxe's control template with a treeview. I've tried different things, but here's what I have so far:
<Style TargetType="{x:Type local:MaroisDropDownTree}">
<pre>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border Margin="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding BorderThickness}">
<TreeView ItemsSource="{Binding TreeData, RelativeSource ={RelativeSource TemplatedParent}}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
When I run it and drop it down, there's nothing there.
Can someone please point me in the right direction?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
How would you implement this as a custom control? I know the ControlTemplate would have to be overridden, but I'm fuzzy on how to do it.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
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!!!
|
|
|
|
|