|
When you click the link, it doesn't select the item first, so the SelectedItem won't be what you're expecting.
Try using:
CommandParameter="{Binding}"
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I created this dummy control to ask the question... It's a TextBox with 2 buttons.
If I wanted to give this control in an assembly to another developer, how would they modify the style to fit their needs? You can see I have named my brushes with some care, but what about changing triggers or maybe animations and other things? If this is all inside an assembly, how does the developer know how the style works what the style does?
Generica.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyControl">
<SolidColorBrush x:Key="Button.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="Button.Normal.Background" Color="BlanchedAlmond"/>
<SolidColorBrush x:Key="Button.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="Button.Hover.Background" Color="Orange"/>
<SolidColorBrush x:Key="Button.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Foreground" Color="Salmon"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="TextBlock.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="TextBlock.Normal.Background" Color="BlanchedAlmond"/>
<SolidColorBrush x:Key="TextBlock.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBlock.Hover.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="TextBlock.Hover.Foreground" Color="Blue"/>
<SolidColorBrush x:Key="TextBlock.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Foreground" Color="Blue"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="TextBlock.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBlock.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="TextBox.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="TextBox.Normal.Background" Color="White"/>
<SolidColorBrush x:Key="TextBox.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBox.Hover.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="TextBox.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="TextBox.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="TextBox.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="TextBox.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBox.Disabled.Background" Color="#FFF4F4F4"/>
<Geometry x:Key="addButtonPathData">
M20 14H14V20H10V14H4V10H10V4H14V10H20V14Z
</Geometry>
<Geometry x:Key="removeButtonPathData">
M20 14H4V10H20V14Z
</Geometry>
<Style x:Key="pathImageButtonStyle"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Background" Value="{StaticResource Button.Normal.Background}"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Width" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PathImageButton}">
<Grid x:Name="Grid">
<Border x:Name="border"
Margin="2"
Background="{StaticResource Button.Normal.Background}"
BorderBrush="DarkGray"
BorderThickness="1"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="0"
x:Name="path"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{Binding PathData, RelativeSource={RelativeSource TemplatedParent}}"
Fill="{StaticResource Button.Normal.Foreground}"
Stretch="Uniform"
Margin="4"/>
<TextBlock Grid.Column="1"
x:Name="caption"
Text="{Binding Caption, RelativeSource={RelativeSource TemplatedParent}}"
Foreground="{StaticResource TextBlock.Normal.Foreground}"
Background="{StaticResource TextBlock.Normal.Background}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="0,2,2,2"/>
</Grid>
</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 TextBlock.Hover.Foreground}" />
<Setter TargetName="border" Property="Background" Value="{StaticResource Button.Hover.Background}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Hover.Border}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Pressed.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource TextBlock.Pressed.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Pressed.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 TextBlock.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="buttonBaseStyle"
BasedOn="{StaticResource pathImageButtonStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="addButtonStyle"
BasedOn="{StaticResource buttonBaseStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Caption" Value="Add"/>
<Setter Property="PathData" Value="{StaticResource addButtonPathData}"/>
</Style>
<Style x:Key="removeButtonStyle"
BasedOn="{StaticResource buttonBaseStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Caption" Value="Remove"/>
<Setter Property="PathData" Value="{StaticResource removeButtonPathData}"/>
</Style>
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Width="{Binding Width, RelativeSource={RelativeSource TemplatedParent}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height=""/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0"
Grid.Column="0"
Orientation="Horizontal"
HorizontalAlignment="Stretch">
<TextBox Background="{StaticResource TextBox.Normal.Background}"
FontSize="18"
VerticalContentAlignment="Center"
Width="250"
Margin="2"/>
<local:PathImageButton Style="{StaticResource addButtonStyle}"/>
<local:PathImageButton Style="{StaticResource removeButtonStyle}"
IsEnabled="True"/>
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Well, the easiest way to let people know is if you document the styles just the way you have here. If people want to adjust the triggers and templates, they can see what is affected just by reading the documentation.
|
|
|
|
|
I am working on this Navigation control[^].
See this earlier post[^] The code is in this repository[^].
What I'm trying to accomplish now is to have each Pane load individually only when expanded.
I added a Func that I want to use inside the pane to call the data
<pre>NavigationPaneInfos = new List<NavigationPaneModel>
{
new NavigationPaneModel
{
Header = "Projects",
NavigationItemType = NavigationItemType.Project,
IsExpanded = true,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Inventory",
NavigationItemType = NavigationItemType.Inventory,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Companies" ,
NavigationItemType = NavigationItemType.Company,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Employees",
NavigationItemType = NavigationItemType.Employee,
DataSource = Repository.GetNavigationItems
}
};
Next I modified the outer container's loading
private void Load()
{
if (NavigationPanes != null)
{
ContainerItems = new List<NavigationPane>();
foreach (var navigationPaneModel in NavigationPanes)
{
var navigationPane = new NavigationPane
{
Header = navigationPaneModel.Header ?? "",
ItemType = navigationPaneModel.NavigationItemType,
NavigationPaneModel = navigationPaneModel
};
ContainerItems.Add(navigationPane);
navigationPane.IsExpanded = navigationPaneModel.IsExpanded;
}
}
}
Finally, I changed the pane loading to only happen when IsExpanded is changed:
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded",
typeof(bool),
typeof(NavigationPane),
new PropertyMetadata(false, new PropertyChangedCallback(OnIsExpandedChanged)));
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
private static async void OnIsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.NavigationPaneModel != null)
{
await control.Load();
}
}
private async Task Load()
{
if (NavigationPaneModel != null && NavigationPaneModel.DataSource != null)
{
var dataSource = NavigationPaneModel.DataSource(NavigationPaneModel.NavigationItemType);
List<NavigationEntity>? data = null;
if (dataSource != null)
{
data = await Task.Run(() => dataSource);
}
if (data != null)
{
Items = new ObservableCollection<NavigationEntity>(data);
}
}
}
It's throwing a binding error when I invoke the func.
A 'Binding' cannot be set on the 'Header' property of type 'NavigationPane'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'
Yet the Header property IS a DP.
I've been staring it this for hours. I would appreciate some help. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
That's a nice simple one!
In NavigationPane.cs you have:
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header",
typeof(string),
typeof(NavigationContainer),
new PropertyMetadata("", new PropertyChangedCallback(OnHeaderChanged))); The ownerType needs to be typeof(NavigationPane) instead:
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header",
typeof(string),
typeof(NavigationPane),
new PropertyMetadata("", new PropertyChangedCallback(OnHeaderChanged)));
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
LOL. I stared at this forever.
I need a vacation
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
OK, so I'm close to done with this, but there's still a related problem.
In the MainWindow's code behind I have
NavigationPaneInfos = new List<NavigationPaneModel>
{
new NavigationPaneModel
{
Header = "Projects",
NavigationItemType = NavigationItemType.Project,
DataSource = Repository.GetNavigationItems,
IsExpanded = true
},
new NavigationPaneModel
{
Header = "Inventory",
NavigationItemType = NavigationItemType.Inventory,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Companies" ,
NavigationItemType = NavigationItemType.Company,
DataSource = Repository.GetNavigationItems,
IsExpanded = true
},
new NavigationPaneModel
{
Header = "Employees",
NavigationItemType = NavigationItemType.Employee,
DataSource = Repository.GetNavigationItems
}
};
Here's the Pane's NavigationModel DP
public static readonly DependencyProperty NavigationPaneModelProperty =
DependencyProperty.Register("NavigationPaneModel",
typeof(NavigationPaneModel),
typeof(NavigationPane),
new PropertyMetadata(null, new PropertyChangedCallback(OnNavigationPaneModelChanged)));
public NavigationPaneModel NavigationPaneModel
{
get { return (NavigationPaneModel)GetValue(NavigationPaneModelProperty); }
set { SetValue(NavigationPaneModelProperty, value); }
}
private static async void OnNavigationPaneModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.NavigationPaneModel.IsExpanded)
{
control.IsPaneExpanded = true;
}
}
The IsPaneExpanded DP
public static readonly DependencyProperty IsPaneExpandedProperty =
DependencyProperty.Register("IsPaneExpanded",
typeof(bool),
typeof(NavigationPane),
new PropertyMetadata(false, new PropertyChangedCallback(OnIsPaneExpandedChanged)));
public bool IsPaneExpanded
{
get { return (bool)GetValue(IsPaneExpandedProperty); }
set { SetValue(IsPaneExpandedProperty, value); }
}
private static async void OnIsPaneExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.IsPaneExpanded)
{
if (control.NavigationPaneModel != null)
{
await control.Load();
}
}
}
In addition, even though IsPaneExpanded is getting set to True, the pane never expands. I'm not getting any binding errors, and you can see the code behind is getting called.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The problem is you have two instances of the NavigationPane for each expander - one that you create through code and add to the ContainerItems property, and one that's declared in XAML.
You don't have a binding for the NavigationPaneModel property in the XAML, so that property doesn't propagate from the ContainerItems instance to the XAML instance.
If you add a binding, then the property won't be null:
<ctrls:NavigationPane BorderBrush="Orange"
BorderThickness="3"
Background="Red"
NavigationPaneModel="{Binding NavigationPaneModel}"
Header="{Binding Header}"
Items="{Binding Items}"
Margin="0,0,0,1"/>
Alternatively, remove the ListBox.ItemTemplate so that the list displays the items created in code. You can use a style to set the additional properties:
<ListBox Grid.Row="1"
Margin="1"
BorderThickness="1"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ContainerItems, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.Resources>
<Style TargetType="ctrls:NavigationPane">
<Setter Property="BorderBrush" Value="Orange" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Background" Value="Red" />
<Setter Property="Margin" Value="0,0,0,1" />
</Style>
</ListBox.Resources>
</ListBox>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I have started on a project that involves using loading resources on the new glTF format. Namely it from NASAs 3D models of the Solar system:
Sun 3D Model | NASA Solar System Exploration[^]
The glTF format seems to be easy to load using the glTFLoader that can be downloaded from github. The file itself is just a mix of some header info, a JSON part, and a Binary data part that is pretty well described in the documentation. glTF-Tutorials/gltfTutorial_002_BasicGltfStructure.md at master · KhronosGroup/glTF-Tutorials · GitHub[^]
But it is not working exactly. First issue is that the images are loaded, but the texture coordinates seems to be wrong. I have asked this question over at the site that monitors the standard. Load glTF into WPF 3D with a simple viewer - glTF - Khronos Forums[^].
The second issue, which I hope some of you might help me with, is that the diffuse material does not seem to register correctly. So I have to set this via a name property on the diffuse material itself. Then it loads. Any ideas on why that is?
using glTFLoader.Schema;
using glTFLoader;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows;
namespace Wpf_glTF_testing
{
public class Earth
{
public UInt32 Magic { get; private set; }
public UInt32 Version { get; private set; }
public UInt32 TotalFileLength { get; private set; }
public UInt32 JsonChuckLength { get; private set; }
public UInt32 BinChuckLength { get; private set; }
public byte[] JSON_data { get; private set; }
public byte[] BIN_data { get; private set; }
UInt32 JSON_hex = 0x4E4F534A;
UInt32 BIN_hex = 0x004E4942;
public Point3DCollection MaterialPoints { get; private set; } = new Point3DCollection();
public Vector3DCollection NormalPoints { get; private set; } = new Vector3DCollection();
public PointCollection TexturePoints { get; private set; } = new PointCollection();
public Int32Collection Indecies { get; private set; } = new Int32Collection();
public MeshGeometry3D Model3D { get; private set; }
public GeometryModel3D GeoModel3D { get;set; } = new GeometryModel3D();
public List<BitmapImage> Images { get; private set; } = new List<BitmapImage>();
public Earth(string filename = "Earth_1_12756.glb")
{
Gltf test = Interface.LoadModel(filename);
using (var stream = File.Open(filename, FileMode.Open))
{
using (var reader = new BinaryReader(stream, Encoding.UTF8, false))
{
Magic = reader.ReadUInt32();
Version = reader.ReadUInt32();
TotalFileLength = reader.ReadUInt32();
JsonChuckLength = reader.ReadUInt32();
UInt32 chunckType = reader.ReadUInt32();
string hexValue = chunckType.ToString("X");
JSON_data = reader.ReadBytes((int)JsonChuckLength);
BinChuckLength = reader.ReadUInt32();
UInt32 chunckType2 = reader.ReadUInt32();
string hexValue2 = chunckType2.ToString("X");
BIN_data = reader.ReadBytes((int)BinChuckLength);
}
}
int PosisionOrNormals = 0;
foreach (glTFLoader.Schema.Accessor item in test.Accessors)
{
var BufferViewIndex = item.BufferView;
BufferView BufferView = test.BufferViews[(int)BufferViewIndex];
var Offset = BufferView.ByteOffset;
var Length = BufferView.ByteLength;
if (item.ComponentType == Accessor.ComponentTypeEnum.FLOAT)
{
if (item.Type == Accessor.TypeEnum.VEC3)
{
float[] ScalingFactorForVariables = new float[3];
if (item.Max == null)
ScalingFactorForVariables = new float[3] { 1.0f, 1.0f, 1.0f };
else
ScalingFactorForVariables = item.Max;
float UpscalingFactor = 1.5f;
Point3DCollection PointsPosisions = new Point3DCollection();
Vector3DCollection NormalsForPosisions = new Vector3DCollection();
for (int n = Offset; n < Offset + Length; n += 4)
{
float x = BitConverter.ToSingle(BIN_data, n) / ScalingFactorForVariables[0] * UpscalingFactor;
n += 4;
float y = BitConverter.ToSingle(BIN_data, n) / ScalingFactorForVariables[1] * UpscalingFactor;
n += 4;
float z = BitConverter.ToSingle(BIN_data, n) / ScalingFactorForVariables[2] * UpscalingFactor;
PointsPosisions.Add(new Point3D(x, y, z));
NormalsForPosisions.Add(new Vector3D(x, y, z));
}
if (PosisionOrNormals == 0)
MaterialPoints = PointsPosisions;
else
NormalPoints = NormalsForPosisions;
PosisionOrNormals++;
}
if (item.Type == Accessor.TypeEnum.VEC2)
{
PointCollection vec2 = new PointCollection();
for (int n = Offset; n < Offset + Length; n += 4)
{
double x = Math.Round((double)BitConverter.ToSingle(BIN_data, n),2);
n += 4;
double y = Math.Round((double)BitConverter.ToSingle(BIN_data, n), 2);
vec2.Add(new Point((double)x, (double)y));
}
TexturePoints = vec2;
}
}
else if (item.ComponentType == Accessor.ComponentTypeEnum.UNSIGNED_SHORT)
{
List<UInt16> TriangleIncidence = new List<UInt16>();
for (int n = Offset; n < Offset + Length; n += 2)
{
UInt16 TriangleItem = BitConverter.ToUInt16(BIN_data, n);
Indecies.Add((Int32)TriangleItem);
}
}
}
foreach (glTFLoader.Schema.Image item in test.Images)
{
int BufferViewIndex = (int)item.BufferView;
BufferView BufferView = test.BufferViews[BufferViewIndex];
var Offset = BufferView.ByteOffset;
var Length = BufferView.ByteLength;
byte[] ImageBytes = new byte[Length];
Array.Copy(BIN_data, Offset, ImageBytes, 0, Length);
MemoryStream ms = new MemoryStream(ImageBytes);
BitmapImage Img = new BitmapImage();
Img.BeginInit();
Img.StreamSource = ms;
Img.EndInit();
Images.Add(Img);
}
Model3D = new MeshGeometry3D();
Model3D.TriangleIndices = Indecies;
Model3D.Positions = MaterialPoints;
Model3D.Normals = NormalPoints;
Model3D.TextureCoordinates = TexturePoints;
GeoModel3D.Geometry = Model3D;
GeoModel3D.Material = new DiffuseMaterial() { Brush = Brushes.Blue };
}
}
}
|
|
|
|
|
You abstract "... new DiffuseMaterial(), etc." to a separate WPF project; get it working there; then import it back.
(Someone was dealing with "DiffuseMaterial" and 3rd party software in Q&A and not getting anywhere either).
"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 figured it out anyways.
|
|
|
|
|
|
|
I'm working on this control[^]. The code is in this repository[^].
It has a listbox filled with expanders. I can't seem to get the expanders to size horizontally corrrectly. The expanders should horizontally fill inside the listboxitem.
This is what I'm gettting[^]
I tried binding the width of the expander to the width of the listboxitem, but it gives some strange results.
See this[^]
I found some Google hits that say to set the width of the expanders header content. Here's one example[^]. I've tried this and it has the same affect as in my second picture.
And, even more strange, when I do try to bind the width, the vertical scrollbar on the right is visible and enabled, but no longer drags to scroll. Mouse wheel scrolling is unafffected
Anyone know the right 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.
|
|
|
|
|
Remove the Width binding and the HorizontalAlignment on the ctrls:NavigationPane element. Instead, set the HorizontalContentAlignment property on the ListBox .
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:ctrls="clr-namespace:NavigationContainer">
<Style TargetType="{x:Type ctrls:NavigationPane}">
<Setter Property="MaxHeight" Value="300"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrls:NavigationPane}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Expander Header="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"
Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}}"
Margin="{Binding Margin, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
IsExpanded="True">
<Grid>
<ListBox ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Margin="2"
BorderBrush="Transparent"
BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Caption}"
Margin="2"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Expander>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ctrls:NavigationContainer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrls:NavigationContainer}">
<Border Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}}"
Margin="{Binding Margin, RelativeSource={RelativeSource TemplatedParent}}"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="1"
Margin="1"
BorderThickness="1"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ContainerItems, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<ctrls:NavigationPane
BorderBrush="Orange"
BorderThickness="3"
Background="Red"
Header="{Binding Header}"
Items="{Binding Items}"
Margin="0,0,0,1"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary> xaml - How to get a ListBox ItemTemplate to stretch horizontally the full width of the ListBox? - Stack Overflow[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it.
I spent hours trying to figure that out. It seems in this case all the properties have to be just right.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have a spinning indicator custom control[^]. It's currently in a UserControl that works fine. But now I want to put it in a CustomControl instead.
It's throwing this exception. If I comment out the DoubleAnimation then it doesn't throw, but it also doesn't show anything.
Cannot resolve all property references in the property path 'RenderTransform.Angle'. Verify that applicable objects support the properties.
Inner Exception 1:
InvalidOperationException: Cannot resolve all property references in the property path 'RenderTransform.Angle'. Verify that applicable objects support the properties.
I'm stumped on this. Anyone know what's wrong?
Code behind
It has properties for the Indicator Color, Indicator Text Color, and Message:
public class MaroisSpinningProgress : ControlBase
{
#region DP IndicatorColor
public static readonly DependencyProperty IndicatorColorProperty =
DependencyProperty.Register("IndicatorColor",
typeof(SolidColorBrush),
typeof(MaroisSpinningProgress),
new PropertyMetadata(new SolidColorBrush(Colors.Black), new PropertyChangedCallback(OnIndicatorColorChanged)));
public SolidColorBrush IndicatorColor
{
get { return (SolidColorBrush)GetValue(IndicatorColorProperty); }
set { SetValue(IndicatorColorProperty, value); }
}
private static void OnIndicatorColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (MaroisSpinningProgress)d;
}
#endregion
#region DP IndicatorTextColor
public static readonly DependencyProperty IndicatorTextColorProperty =
DependencyProperty.Register("IndicatorTextColor",
typeof(SolidColorBrush),
typeof(MaroisSpinningProgress),
new PropertyMetadata(new SolidColorBrush(Colors.Black)));
public SolidColorBrush IndicatorTextColor
{
get { return (SolidColorBrush)GetValue(IndicatorTextColorProperty); }
set { SetValue(IndicatorTextColorProperty, value); }
}
#endregion
#region DP Message
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message",
typeof(string),
typeof(MaroisSpinningProgress),
new PropertyMetadata("", new PropertyChangedCallback(OnMessageChanged)));
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
private static void OnMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (MaroisSpinningProgress)d;
}
#endregion
#region CTOR
public MaroisSpinningProgress()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MaroisSpinningProgress),
new FrameworkPropertyMetadata(typeof(MaroisSpinningProgress)));
}
#endregion
}
XAML
<Style TargetType="{x:Type local:MaroisSpinningProgress}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MaroisSpinningProgress}">
<Viewbox HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid Background="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Canvas Name="Canvas1"<br />
RenderTransformOrigin="0.5,0.5"<br />
HorizontalAlignment="Center"<br />
VerticalAlignment="Center"
Width="120"
Height="120"
Margin="15">
<Canvas.RenderTransform>
<RotateTransform Angle="0" />
</Canvas.RenderTransform>
<Canvas.Style>
<Style TargetType="Canvas">
<Style.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="Storyboard_Rotate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
From="0"
To="360"
Duration="0:0:3"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard_Rotate" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="1.0" Canvas.Left="50" Canvas.Top="0" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.9" Canvas.Left="20.6107373853764" Canvas.Top="9.54915028125262" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.8" Canvas.Left="2.44717418524233" Canvas.Top="34.5491502812526" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.7" Canvas.Left="2.44717418524232" Canvas.Top="65.4508497187474" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.6" Canvas.Left="20.6107373853763" Canvas.Top="90.4508497187474" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.5" Canvas.Left="50" Canvas.Top="100" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.4" Canvas.Left="79.3892626146236" Canvas.Top="90.4508497187474" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.3" Canvas.Left="97.5528258147577" Canvas.Top="65.4508497187474" />
<Ellipse Width="20" Height="20" Stretch="Fill" Fill="{Binding IndicatorColor, Mode=TwoWay}" Opacity="0.2" Canvas.Left="97.5528258147577" Canvas.Top="34.5491502812526" />
</Canvas>
<TextBlock Grid.Row="1"
Text="{Binding Message}"
FontSize="18"
Foreground="{Binding IndicatorTextColor}"
Visibility="{Binding IsShowingText}"/>
</Grid>
</Viewbox>
</ControlTemplate>
</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.
|
|
|
|
|
The "target" is the RotateTransform; the "target property" is "Angle".
"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'm sorry, I don't think I understand. Isn't that what I have here
<Canvas.RenderTransform>
<RotateTransform Angle="0" />
</Canvas.RenderTransform>
and here
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
From="0"
To="360"
Duration="0:0:3"/>
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 RotateTransform a "Name"; then reference it in "TargetName" of the StoryBoard. Where in "RenderTransform" (abstract Transform) is there an "Angle" property?
"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'm trying to create a flat button style:
Style
<Style x:Key="buttonStyle"
TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Width" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
Margin="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextElement.Foreground="{TemplateBinding Foreground}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Hover.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Pressed.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage
<Button Grid.Row="5"
Grid.Column="0"
IsDefault="True"
Content="Test"
Command="{Binding SignInCommand}"
Style="{DynamicResource buttonStyle}"
Background="LightSeaGreen"
Foreground="Red"
Margin="0,25,0,0"/>
The problem is that the foreground doesn't change. I know it's probably the ContentPresenter, but I don't know what to do about it. What's the right way to fix this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Doesn't change from what to what? Is it "Red"?
"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
|
|
|
|
|
Sorry I wasn't clear.
I set it to red but it shows as black.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|