WPF View not Updated position after update Model - c#

I have next structure:
Main window
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Margin="100 70 0 0">
<local:RotateControl x:Name="rtc1" Panel.ZIndex="1"
Width="{Binding ElementName=window, Path=ActualHeight, Converter={StaticResource SizeConverter}}"
Height="{Binding ElementName=window, Path=ActualHeight, Converter={StaticResource SizeConverter}}"
Radius="{Binding ElementName=window, Path=ActualHeight, Converter={StaticResource RadiusConverter}}"
Loaded="rtc1_Loaded" SizeChanged="rtc1_SizeChanged"/>
</Grid>
<StackPanel HorizontalAlignment="Right" Canvas.Right="80" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBox x:Name="year" Width="40"></TextBox>
<TextBox x:Name="month" Width="20"></TextBox>
<TextBox x:Name="day" Width="20"></TextBox>
<TextBox x:Name="hour" Width="20"></TextBox>
<TextBox x:Name="min" Width="20"></TextBox>
<TextBox x:Name="sec" Width="20"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox x:Name="lat" Width="80" Text="55.75"></TextBox>
<TextBox x:Name="lng" Width="80" Text="37.583333"></TextBox>
</StackPanel>
<ComboBox x:Name="cbHSys" Width="300" SelectedIndex="0"></ComboBox>
<Button x:Name="GatData" Click="GatData_Click">Get data</Button>
<ScrollViewer>
<Label x:Name="julday"></Label>
</ScrollViewer>
</StackPanel>
</Canvas>
Custom control
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Astro"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<local:XLineCoordConverter x:Key="XLineCoordConverter" />
<local:YLineCoordConverter x:Key="YLineCoordConverter" />
<SolidColorBrush x:Key="Blue1Brush" Color="#e2edfa" />
<SolidColorBrush x:Key="Blue2Brush" Color="#0080c0" />
<Pen x:Key="BlackPen1" Thickness="1" Brush="Black"></Pen>
<Pen x:Key="BluePen1" Thickness="0.1" Brush="{StaticResource Blue2Brush}"></Pen>
<Style TargetType="{x:Type local:RotateControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:RotateControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Background="Transparent">
<Line X1="{Binding Path=Radius}" Y1="{Binding Path=Radius}" Stroke="White" StrokeThickness="1">
<Line.X2>
<MultiBinding Converter="{StaticResource XLineCoordConverter}" ConverterParameter="1">
<Binding Path="Radius"/>
<Binding Path="House1"/>
<Binding Path="House2"/>
</MultiBinding>
</Line.X2>
<Line.Y2>
<MultiBinding Converter="{StaticResource YLineCoordConverter}" ConverterParameter="1">
<Binding Path="Radius"/>
<Binding Path="House1"/>
<Binding Path="House2"/>
</MultiBinding>
</Line.Y2>
</Line>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And model:
public class CircleModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
double _radius;
public double Radius
{
get
{
return _radius;
}
set
{
if (_radius == value) return;
_radius = value;
OnPropertyChanged("Radius");
}
}
double _angel;
public double Angel
{
get
{
return _angel;
}
set
{
if (_angel == value) return;
_angel = value;
OnPropertyChanged("Angel");
}
}
double _house1;
public double House1
{
get
{
return _house1;
}
set
{
if (_house1 == value) return;
_house1 = value;
OnPropertyChanged("House1");
}
}
...................
}
And code for change data:
private void GetData()
{
julday.Content = "";
//SetCurDate();
DateTime date = new DateTime(Convert.ToInt32(year.Text), Convert.ToInt32(month.Text), Convert.ToInt32(day.Text),
Convert.ToInt32(hour.Text), Convert.ToInt32(min.Text), Convert.ToInt32(sec.Text));
CalcNatalChart(date);
_model.Radius = (this.ActualHeight - (this.ActualHeight > 150 ? 150 : 0)) / 2;
this.ViewModel = _model;
}
private void GatData_Click(object sender, RoutedEventArgs e)
{
GetData();
}
private void rtc1_Loaded(object sender, RoutedEventArgs e)
{
GetData();
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1.0);
_timer.Tick += timer_Tick;
_timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
julday.Content = "";
CalcNatalChart(DateTime.Now);
_model.Radius = (this.ActualHeight - (this.ActualHeight > 150 ? 150 : 0)) / 2;
this.ViewModel = _model;
}
All data in the form of updated correctly but View not. Only if press button GatData_Click. Dynamically change the data does not work.
Can you help me to solve it problem? Thanks

The problem is in these lines:
_model.Radius = (this.ActualHeight - (this.ActualHeight > 150 ? 150 : 0)) / 2;
this.ViewModel = _model;
After you reassign ViewModel, the view doesn't know about this change and uses old object instance. Either initialize ViewModel only once in constructor and then change it's properties or make that ViewModel property also observable so that you could notify when the data is changed.

Try this one...
instead of your this.ViewModel = _model; put this.ViewModel.Radious = _model.Radious;

Related

Horizontal dynamic listbox with insert buttons

I would like to create an horizontal dynamic listbox:
A button is visible when the mouse is between two items.
<ListBox
MinHeight="32"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
SelectionMode="Extended"
HorizontalAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>
<TextBlock><Run Text="C1" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C2" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C3" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C4" /></TextBlock>
</ListBoxItem>
</ListBox>
</ListBox>
Any suggestions, please?
Thank you
EDIT
private void myElement_MouseEnter(object sender, MouseEventArgs e)
{
//change button visibility
if (sender is Grid item)
{
if (item.DataContext is DataModel data)
{
System.Diagnostics.Debug.WriteLine("myElement_MouseEnter: " + data.TextValue);
}
var border1 = (Border)item.FindName("HitTestBorder1");
var border2 = (Border)item.FindName("HitTestBorder2");
if (border1 is Border)
{
var margin = border1.Margin;
margin.Left = -item.ActualWidth;
border1.Margin = margin;
}
if (border2 is Border)
{
var margin = border2.Margin;
margin.Left = item.ActualWidth;
border2.Margin = margin;
}
}
}
The problem is that the grid width is resized after mouse_enter... So, I don't get the overlay "effect".
Here is the solution.
I created a canvas. It contains 2 borders with button inside and ZPanel is setted very high (=1000) to be on top of everything.
I change the position of these borders on MouseEnter and MouseLeave events of ListBoxItem (see ItemTemplate).
XAML
<Border Padding="10">
<Canvas x:Name="supergrid" MouseLeave="supergrid_MouseLeave">
<Border x:Name="HitTestBorder1"
Panel.ZIndex="1000"
Background="Transparent"
BorderBrush="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderThickness="0,0,0,0" >
<Button x:Name="button1"
Visibility="Hidden"
Content="+"
Height="18" Width="18" FontSize="6" Background="Red"
Click="button1_Click"
/>
</Border>
<Border x:Name="HitTestBorder2"
Panel.ZIndex="1000"
Background="Transparent"
BorderBrush="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderThickness="1,1,1,1" >
<Button x:Name="button2"
Visibility="Hidden"
Content="+"
Height="18" Width="18" FontSize="6" Background="Green"
Click="button2_Click"
/>
</Border>
<ListBox x:Name="HorizontalListBox"
ItemsSource="{Binding DataModels}"
Margin="0,0,0,0"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Background="Yellow" MouseLeave="HorizontalListBox_MouseLeave">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<!--<Setter Property="MinWidth" Value="60" />
<Setter Property="MinHeight" Value="40" />-->
<Setter Property="Background" Value="Blue" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="myElement"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MouseEnter="myElement_MouseEnter"
MouseLeave="myElement_MouseLeave"
Background="White">
<TextBlock x:Name="myText"
Margin="10"
Text="{Binding TextValue}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Canvas>
</Border>
C#
public partial class MainWindow : Window
{
private DataModel currentDataModel;
public ObservableCollection<DataModel> DataModels { get; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.DataModels = new ObservableCollection<DataModel>();
this.DataModels.Add(new DataModel("Item1"));
this.DataModels.Add(new DataModel("Item2"));
this.DataModels.Add(new DataModel("SuperMegaHyperLong"));
this.DataModels.Add(new DataModel("Item3"));
this.DataModels.Add(new DataModel("Item4"));
this.DataModels.Add(new DataModel("123"));
this.DataModels.Add(new DataModel("Item5"));
}
private void myElement_MouseEnter(object sender, MouseEventArgs e)
{
updateOverlay((Grid)sender);
}
private void updateOverlay(Grid lbi)
{
if (lbi is Grid item) //the grid of listboxitem
{
if (item.DataContext is DataModel data)
{
Debug.WriteLine("myElement_MouseEnter: " + data.TextValue);
}
var myText = (TextBlock)item.FindName("myText");
if (myText is TextBlock)
{
Point relativePoint = myText.TransformToAncestor(supergrid)
.Transform(new Point(0, 0));
Debug.WriteLine("relativePoint: " + relativePoint.ToString());
//update left button position
double w = button1.ActualWidth;
double h = button1.ActualHeight;
double x = relativePoint.X - w / 2.0 - myText.Margin.Left;
double y = relativePoint.Y;
updateMargin(HitTestBorder1,
x,
x + w,
y + h,
y);
//update right button position
w = button2.ActualWidth;
h = button2.ActualHeight;
x = relativePoint.X - w / 2.0 - myText.Margin.Left;
x += item.ActualWidth;
y = relativePoint.Y;
updateMargin(HitTestBorder2,
x,
x + w,
y + h,
y);
//show the button
button1.Visibility = button2.Visibility = Visibility.Visible;
//the current item
if (myText.DataContext is DataModel dm)
{
this.currentDataModel = dm;
}
}
}
}
private void updateMargin(Border border, double left, double right, double bottom, double top)
{
//border = HitTestBorder2;
var margin = border.Margin;
margin.Left = left;
margin.Right = right;
margin.Top = top;
margin.Bottom = bottom;
border.Margin = margin;
Debug.WriteLine("updateMargin Left: " + left.ToString() + "Right: " + right.ToString());
}
private void myElement_MouseLeave(object sender, MouseEventArgs e)
{
//change button visibility
if (sender is Grid item)
{
if (item.DataContext is DataModel data)
{
System.Diagnostics.Debug.WriteLine("myElement_MouseLeave: " + data.TextValue);
}
//button1.Visibility = button2.Visibility = Visibility.Hidden;
}
}
private void HorizontalListBox_MouseLeave(object sender, MouseEventArgs e)
{
Debug.WriteLine("HorizontalListBox_MouseLeave");
//button1.Visibility = button2.Visibility = Visibility.Hidden;
}
private void supergrid_MouseLeave(object sender, MouseEventArgs e)
{
Debug.WriteLine("supergrid_MouseLeave: ");
button1.Visibility = button2.Visibility = Visibility.Hidden;
// => :D
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("LEFT INSERT");
int idx = this.DataModels.IndexOf(currentDataModel);
DataModel newDataModel = new DataModel($"Item{this.DataModels.Count}");
this.DataModels.Insert(idx, newDataModel);
button1.Visibility = button2.Visibility = Visibility.Hidden;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("RIGHT INSERT");
int idx = this.DataModels.IndexOf(currentDataModel);
this.DataModels.Insert(idx+1, new DataModel($"Item{this.DataModels.Count}"));
button1.Visibility = button2.Visibility = Visibility.Hidden;
}
}
public class DataModel
{
public string TextValue { get; set; }
public DataModel(string textValue)
{
this.TextValue = textValue;
}
}
As you can see, there is place for improvements (like select the new ListBoxItem). Disable the buttons when we drag, animation, delay, etc.

wpf c# datagrid GroupStyle - which rows are expanded

I have the following WPF DataGrid with GroupStyle. I need to now which rows are expanded when I have expanded/collapsed event.
I add:
Expanded="Expander_Process" Collapsed="Expander_Process"
but in the event function Expander_Process when I try to get the row
var row = DataGridRow.GetRowContainingElement(expander);
if (row == null)
then the row is null. So my question is: how can I know which rows are expanded in the datagrid?
<DataGrid x:Name="gvOptionChain" AutoGenerateColumns="False" FontWeight="Bold" Background="#FF262626" Foreground="White" Width="1509"
ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto"
Margin="53,120,89,4.333" HorizontalContentAlignment="Right" SelectionChanged="gvOptionChain_SelectionChanged" VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit ="Item" VirtualizingPanel.VirtualizationMode="Recycling" EnableRowVirtualization="True" EnableColumnVirtualization = "True"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionUnit="Cell" SelectedItem="{Binding SelectedItem, Mode=OneWay}" >
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="False" Foreground="#FFEEEEEE" Expanded="Expander_Process" Collapsed="Expander_Process" >
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupItem}}, Converter={StaticResource ResourceKey=groupToTitleConverter}}" />
</StackPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
private void Expander_Process(object sender, RoutedEventArgs e)
{
if (sender is Expander expander)
{
var row = DataGridRow.GetRowContainingElement(expander);
if (row == null)
{
}
}
}
on the expander event - get the rows that expanded throu
CollectionViewGroup Items1 = ((CollectionViewGroup)(expander.DataContext));
and update a flag about the IsExpanded status of the row . this event happens many times for each expand - so I add timer to process the rows only once
private System.Timers.Timer ExpandTimer;
private bool bIsTimerOn = false;
private void Expander_Process(object sender, RoutedEventArgs e)
{
if (sender is Expander expander)
{
CollectionViewGroup Items1 = ((CollectionViewGroup)(expander.DataContext));
for(int i = 0; i < Items1.Items.Count; i++)
{
OptScrtyData ScrtyData1 = (OptScrtyData)Items1.Items[i];
ScrtyData1.IsExpanded = expander.IsExpanded;
}
if (bIsTimerOn == false)
{
ExpandTimer.Start();
bIsTimerOn = true;
}
}
}
a better answer - activate the timer only if there is new expand status :
private void Expander_Process(object sender, RoutedEventArgs e)
{
if (sender is Expander expander)
{
CollectionViewGroup Items1 = ((CollectionViewGroup)(expander.DataContext));
bool bNewStatus = false;
for(int i = 0; i < Items1.Items.Count; i++)
{
OptScrtyData ScrtyData1 = (OptScrtyData)Items1.Items[i];
if (bNewStatus == false)
{
bNewStatus = ScrtyData1.IsExpanded != expander.IsExpanded;
}
ScrtyData1.IsExpanded = expander.IsExpanded;
}
if (bNewStatus == true)
{
ExpandTimer.Start();
}
}
}

Adding Avg, Min and Max Line to Scatter Chart

I am using a ScatterDataPoint chart in wpf,C#,.NET 3.5 and I have to add 3 horizontal lines for minimum, maximum and average value line that can be different depending on the values that I introduce.
Basically I take some values from a DB and I have to display them in a chart, below you have the basic code from which I started to create my application, but I do not know hoe to add those 3 lines.
here is the XAML code :
<Window.Resources>
<Style x:Key="BubbleDataPointStyle" TargetType="chartingToolkit:ScatterDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:ScatterDataPoint">
<Viewbox x:Name="viewbox">
<Ellipse Width="1px" Height="1px" Fill="Black"/>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Width" Value="3"/>
<Setter Property="Height" Value="3"/>
</Style>
</Window.Resources>
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,-28,0,28">
<Grid Height="921" Background="WhiteSmoke">
<chartingToolkit:Chart Name="lineChart" Title="Power Graph" Background="WhiteSmoke" Foreground="Black" VerticalAlignment="Top" Margin="16,36,20,0" Height="800" IsEnabled="True">
<chartingToolkit:ScatterSeries Title="Points" ItemsSource="{Binding}" DependentValueBinding="{Binding Path=Value}" IndependentValueBinding="{Binding Path=Key}" IsSelectionEnabled="True" DataPointStyle="{StaticResource BubbleDataPointStyle}">
<chartingToolkit:ScatterSeries.IndependentAxis>
<chartingToolkit:LinearAxis Orientation="X" Title="Time (Mins)" Interval="5" />
</chartingToolkit:ScatterSeries.IndependentAxis>
<chartingToolkit:ScatterSeries.DependentRangeAxis>
<chartingToolkit:LinearAxis Orientation="Y" Title="Lenght" x:Name="Yaxis"/>
</chartingToolkit:ScatterSeries.DependentRangeAxis>
</chartingToolkit:ScatterSeries>
</chartingToolkit:Chart>
</Grid>
</ScrollViewer>
</Grid>
</Window>
Here is the code behind, now it just generates a random point:
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer();
ObservableCollection<KeyValuePair<double, double>> Power = new ObservableCollection<KeyValuePair<double, double>>();
public MainWindow()
`enter code here` {
InitializeComponent();
showColumnChart();
timer.Interval = new TimeSpan(0,0,0,0,1); // per 5 seconds, you could change it
timer.Tick += new EventHandler(timer_Tick);
timer.IsEnabled = true;
}
double i = 1;
Random random = new Random();
void timer_Tick(object sender, EventArgs e)
{
Power.Add(new KeyValuePair<double, double>(i, random.NextDouble()));
i += 1;
if(Power.Count==500)
{
timer.IsEnabled = false;
}
}
private void showColumnChart()
{
lineChart.DataContext = Power;
}
}
}
Normally you would use a StripLine for that, but the toolkit doesn't seem to have one. So use an extra LineSeries instead:
XAML:
<Window x:Class="WpfApplication336.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:local="clr-namespace:WpfApplication336"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="BubbleDataPointStyle" TargetType="chartingToolkit:ScatterDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:ScatterDataPoint">
<Viewbox x:Name="viewbox">
<Ellipse Width="1px" Height="1px" Fill="Black"/>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Width" Value="3"/>
<Setter Property="Height" Value="3"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<chartingToolkit:Chart Grid.Row="0" Name="lineChart" Title="Power Graph" Background="WhiteSmoke" Foreground="Black" IsEnabled="True">
<chartingToolkit:Chart.Series>
<chartingToolkit:ScatterSeries Title="Points" ItemsSource="{Binding Power}" DependentValueBinding="{Binding Path=Value}" IndependentValueBinding="{Binding Path=Key}" IsSelectionEnabled="True" DataPointStyle="{StaticResource BubbleDataPointStyle}"/>
<chartingToolkit:LineSeries Title="Average" ItemsSource="{Binding PowerAvg}" DependentValueBinding="{Binding Path=Value}" IndependentValueBinding="{Binding Path=Key}" />
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>
<Button Grid.Row="1" Click="Button_Click">START</Button>
</Grid>
ViewModel:
public class MyViewModel
{
public ObservableCollection<KeyValuePair<double, double>> Power { get; set; }
public ObservableCollection<KeyValuePair<double, double>> PowerAvg { get; set; }
public MyViewModel()
{
Power = new ObservableCollection<KeyValuePair<double, double>>();
PowerAvg = new ObservableCollection<KeyValuePair<double, double>>();
}
public void Add(double x, double y)
{
Power.Add(new KeyValuePair<double, double>(x, y));
double xmin = Power.Min(kvp => kvp.Key);
double xmax = Power.Max(kvp => kvp.Key);
double ymin = Power.Min(kvp => kvp.Value);
double ymax = Power.Max(kvp => kvp.Value);
double yavg = Power.Average(kvp => kvp.Value);
PowerAvg.Clear();
PowerAvg.Add(new KeyValuePair<double, double>(xmin, yavg));
PowerAvg.Add(new KeyValuePair<double, double>(xmax, yavg));
}
}
MainWindow:
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer();
MyViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new MyViewModel();
DataContext = vm;
//showColumnChart();
timer.Interval = new TimeSpan(0, 0, 0, 0, 1); // per 5 seconds, you could change it
timer.Tick += new EventHandler(timer_Tick);
//timer.IsEnabled = true;
}
double i = 1;
Random random = new Random();
void timer_Tick(object sender, EventArgs e)
{
vm.Add(i, random.NextDouble());
i += 1;
if (vm.Power.Count == 250)
{
timer.Stop();
}
}
private void showColumnChart()
{
lineChart.DataContext = vm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
timer.Start();
}
}
You can easily add extra LineSeries for min and max just like we did for the average.

Changing size on control on canvas wpf

I'm stuck and not sure why when the user drags the size-gripper, to resize the control on the canvas, that nothing appears to change. However it does fire and print to the console. What am I missing here that's causing it to not resize the item in wpf. I'm not doing anything really complex either. It's pretty straight forward. I'm assuming the issue is somewhere in the ResizeGizmo.cs. I'm guessing for some reason it's not letting me set the size of the contents of the item it's targeting.
Code
GraphNodeViewModel.cs
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApplication1
{
public class NodeViewModel : NotifyBase
{
// position coordinates
private double x = 0;
public double X
{
get { return x; }
set { Set(ref x, value); }
}
private double y = 0;
public double Y
{
get { return y; }
set { Set(ref y, value); }
}
public double Z { get; set; }
private bool isSelected = false;
public bool IsSelected
{
get { return isSelected; }
set { Set(ref isSelected, value); }
}
private string virtualName = "New Node";
public string VirtualName
{
get { return virtualName; }
set { Set(ref virtualName, value); }
}
public NodeViewModel(string virtualName, double x, double y)
{
this.virtualName = virtualName;
this.X = x;
this.Y = y;
this.Z = 100; // place top most in z space
}
}
public abstract class NotifyBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
RaisePropertyChanged(propertyName);
return true;
}
}
}
ResizeGizmo.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace WpfApplication1
{
public class ResizeGizmo : Thumb
{
public ResizeGizmo()
{
DragDelta += new DragDeltaEventHandler(this.ResizeGizmo_DragDelta);
}
private void ResizeGizmo_DragDelta(object sender, DragDeltaEventArgs e)
{
Console.WriteLine("Resizing");
Control item = this.DataContext as Control;
if (item != null)
{
double deltaVertical, deltaHorizontal;
switch (VerticalAlignment)
{
case VerticalAlignment.Bottom:
deltaVertical = Math.Min(-e.VerticalChange,
item.ActualHeight - item.MinHeight);
item.Height -= deltaVertical;
break;
case VerticalAlignment.Top:
deltaVertical = Math.Min(e.VerticalChange,
item.ActualHeight - item.MinHeight);
Canvas.SetTop(item, Canvas.GetTop(item) + deltaVertical);
item.Height -= deltaVertical;
break;
default:
break;
}
switch (HorizontalAlignment)
{
case HorizontalAlignment.Left:
deltaHorizontal = Math.Min(e.HorizontalChange,
item.ActualWidth - item.MinWidth);
Canvas.SetLeft(item, Canvas.GetLeft(item) + deltaHorizontal);
item.Width -= deltaHorizontal;
break;
case HorizontalAlignment.Right:
deltaHorizontal = Math.Min(-e.HorizontalChange,
item.ActualWidth - item.MinWidth);
item.Width -= deltaHorizontal;
break;
default:
break;
}
}
e.Handled = true;
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="700"
Background="sc#1,.01,.01,.01"
WindowStartupLocation="CenterScreen"
>
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<Style x:Key="SizeGripStyle" TargetType="{x:Type Thumb}">
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
<Setter Property="Background" Value="#3FFFFFFF"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="1" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Resize Template -->
<ControlTemplate x:Key="ResizeGizmoTemplate" TargetType="Control">
<Grid>
<local:ResizeGizmo Height="1" Cursor="SizeNS" Margin="0 -4 0 0" VerticalAlignment="Top" HorizontalAlignment="Stretch" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="1" Cursor="SizeWE" Margin="-4 0 0 0" VerticalAlignment="Stretch" HorizontalAlignment="Left" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="1" Cursor="SizeWE" Margin="0 0 -4 0" VerticalAlignment="Stretch" HorizontalAlignment="Right" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Height="1" Cursor="SizeNS" Margin="0 0 0 -4" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="6" Height="6" Cursor="SizeNWSE" Margin="-6 -6 0 0" VerticalAlignment="Top" HorizontalAlignment="Left" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="6" Height="6" Cursor="SizeNESW" Margin="0 -6 -6 0" VerticalAlignment="Top" HorizontalAlignment="Right" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="6" Height="6" Cursor="SizeNESW" Margin="-6 0 0 -6" VerticalAlignment="Bottom" HorizontalAlignment="Left" Style="{StaticResource SizeGripStyle}"/>
<local:ResizeGizmo Width="6" Height="6" Cursor="SizeNWSE" Margin="0 0 -6 -6" VerticalAlignment="Bottom" HorizontalAlignment="Right" Style="{StaticResource SizeGripStyle}"/>
</Grid>
</ControlTemplate>
<DataTemplate DataType="{x:Type local:NodeViewModel}">
<!--Outside border is used to visualize selection-->
<Border CornerRadius="4"
Padding="20"
BorderThickness="1"
BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=BorderBrush}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=Background}">
<Grid>
<Border>
<Grid>
<Control Template="{StaticResource ResizeGizmoTemplate}"/>
<Border Background="LightBlue" CornerRadius="4" Padding="10">
<TextBox Text="This is cool"/>
</Border>
</Grid>
</Border>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<!-- visual Nodes and Connections -->
<ListBox x:Name="listBox" ItemsSource="{Binding GraphNodes}"
SelectionMode="Extended"
Background="Transparent">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" >
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
<Setter Property="Panel.ZIndex" Value="{Binding Z}" />
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="Background" Value="sc#0.3,1,1,1"/>
<Setter Property="BorderBrush" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.Resources>
</ListBox>
<!-- This Canvas is used to render a drag selection rectangle -->
<Canvas x:Name="dragSelectionCanvas" Visibility="Collapsed" >
<Border
x:Name="dragSelectionBorder"
BorderBrush="White"
BorderThickness="1"
Background="sc#0.1,1,1,1"
CornerRadius="2"
Opacity=".5"
IsHitTestVisible="False"
/>
</Canvas>
</Grid>
</Window>
MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
public class MainWindowViewModel : NotifyBase
{
private ObservableCollection<NodeViewModel> graphNodes = new ObservableCollection<NodeViewModel>();
public ObservableCollection<NodeViewModel> GraphNodes { get { return graphNodes; } }
public MainWindowViewModel()
{
// Populate the view model with some example data.
graphNodes.Add(new NodeViewModel("Type here", 50, 50));
graphNodes.Add(new NodeViewModel("Type in another box here", 180, 150));
graphNodes.Add(new NodeViewModel("This is fun", 160, 70));
graphNodes.Add(new NodeViewModel("Why is this working", 320, 230));
graphNodes.Add(new NodeViewModel("ABC", 20, 170));
}
}
}
Created a working solution!
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace WpfApplication1
{
public class ResizeGizmo : Thumb
{
public ResizeGizmo()
{
DragDelta += new DragDeltaEventHandler(this.ResizeGizmo_DragDelta);
}
private void ResizeGizmo_DragDelta(object sender, DragDeltaEventArgs e)
{
float MinSize = 70;
NodeViewModel node = this.DataContext as NodeViewModel;
var element = sender as FrameworkElement;
if (node != null)
{
double deltaVertical, deltaHorizontal;
switch (VerticalAlignment)
{
case VerticalAlignment.Bottom:
deltaVertical = Math.Min(-e.VerticalChange, node.Height - MinSize);
node.Height -= deltaVertical;
break;
case VerticalAlignment.Top:
deltaVertical = Math.Min(e.VerticalChange, node.Height - MinSize);
node.Y += deltaVertical;
node.Height -= deltaVertical;
break;
default:
break;
}
switch (HorizontalAlignment)
{
case HorizontalAlignment.Left:
deltaHorizontal = Math.Min(e.HorizontalChange, node.Height - MinSize);
node.X += deltaHorizontal;
node.Width -= deltaHorizontal;
break;
case HorizontalAlignment.Right:
deltaHorizontal = Math.Min(-e.HorizontalChange, node.Height - MinSize);
node.Width -= deltaHorizontal;
break;
default:
break;
}
}
e.Handled = true;
}
}
}

How to create a WPF Window without a border that can be resized?

Is there a way in WPF where I can remove the main window's border, yet allow that window to be resized (without grip)?
I realized there's a way to do this scenario by setting resize mode to CanResizeWithGrip. However, I want to be able to do it with the resize mode set to CanResize.
I tried setting the following:
ResizeMode="CanResize"
WindowStyle="None"
AllowsTransparency="True"
However, by setting AllowsTransparency, it removes the ability to resize without the grip. Any ideas how I can pull this off?
I also should note that I can't set AllowsTransparency to true anyway, because I am using a winformshost control in my window, which is not shown when AllowsTransparency is true.
I know this is an old question, but I just wanted to put up a working sample for newcomers.
Xaml Window:
<Window x:Class="CustomWindowDemo.DemoCustomWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CustomWindowDemo"
mc:Ignorable="d"
Title="DemoCustomWindow" Height="300" Width="300" Background="{x:Null}" AllowsTransparency="True" WindowStyle="None">
<Window.Resources>
<Style x:Key="BorderThumb" TargetType="Thumb">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle MinWidth="4" MinHeight="4" StrokeThickness="0">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}" Opacity="0.05"/>
</Rectangle.Fill>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border BorderBrush="#55FFFFFF" BorderThickness="1" CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border MouseMove="Header_MouseMove" DockPanel.Dock="Top" Height="32" Grid.Row="1" Grid.Column="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,3">
<GradientStop Color="#3BB2EA" Offset="0" />
<GradientStop Color="#EFF7FA" Offset="0.3" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
<Button x:Name="btn_Minimize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Click="btn_Minimize_Click" Grid.Column="1">
<Image Source="Resources/Ahmadhania-Spherical-Minimize.ico"/>
</Button>
<Button x:Name="btn_Maximize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="2" Click="btn_Maximize_Click">
<Image Source="Resources/1412181205_61002.ico"/>
</Button>
<Button x:Name="btn_Close" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="3" Click="btn_Close_Click">
<Image Source="Resources/Ahmadhania-Spherical-Close(1).ico"/>
</Button>
</Grid>
</Border>
<Thumb x:Name="ThumbBottom" DragDelta="ThumbBottom_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}" Margin="3,0" Grid.ColumnSpan="3" Grid.Row="3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTop" DragDelta="ThumbTop_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}" Margin="3,0" Grid.ColumnSpan="3" Height="4" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbBottomRightCorner" DragDelta="ThumbBottomRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNWSE" Grid.Row="3" Grid.Column="3" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTopRightCorner" DragDelta="ThumbTopRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNESW" Grid.Row="0" Grid.Column="2" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTopLeftCorner" DragDelta="ThumbTopLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNWSE" Grid.Row="0" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
<Thumb x:Name="ThumbBottomLeftCorner" DragDelta="ThumbBottomLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNESW" Grid.Row="3" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
<Thumb x:Name="ThumbRight" DragDelta="ThumbRight_DragDelta" Cursor="SizeWE" Grid.Column="2" Grid.RowSpan="4" Background="{x:Null}" Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbLeft" DragDelta="ThumbLeft_DragDelta" Cursor="SizeWE" Grid.Column="0" Grid.RowSpan="4" HorizontalContentAlignment="Right" Background="{x:Null}" Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Grid x:Name="Grid_Content" Background="#EFF7FA" Grid.Row="2" Grid.Column="1">
</Grid>
</Grid>
</Border>
</Window>
C# code behind:
using System.Windows.Interop;
using winforms = System.Windows.Forms;
namespace CustomWindowDemo
{
/// <summary>
/// Interaction logic for DemoCustomWindow.xaml
/// </summary>
public partial class DemoCustomWindow : Window
{
bool Maximized = false;
int NormalWidth = 0;
int NormalHeight = 0;
int NormalX = 0;
int NormalY = 0;
public DemoCustomWindow()
{
InitializeComponent();
}
#region Header & Resize
void Header_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
this.DragMove();
}
void ThumbBottomRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbTopRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void ThumbTopLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void ThumbBottomLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbRight_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
}
void ThumbLeft_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
}
void ThumbBottom_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbTop_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void btn_Minimize_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
void btn_Maximize_Click(object sender, RoutedEventArgs e)
{
if (Maximized == true)
{
this.Width = NormalWidth;
this.Height = NormalHeight;
this.Left = NormalX;
this.Top = NormalY;
Maximized = false;
Thumbs();
}
else
{
NormalX = (int)this.Left;
NormalY = (int)this.Top;
NormalHeight = (int)this.Height;
NormalWidth = (int)this.Width;
this.Left = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Left;
this.Top = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Top;
this.Width = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Width;
this.Height = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Height;
Maximized = true;
Thumbs();
}
}
void btn_Close_Click(object sender, RoutedEventArgs e)
{
Close();
}
void Thumbs()
{
if (Maximized == true)
{
ThumbBottom.Visibility = Visibility.Collapsed;
ThumbLeft.Visibility = Visibility.Collapsed;
ThumbTop.Visibility = Visibility.Collapsed;
ThumbRight.Visibility = Visibility.Collapsed;
ThumbTopLeftCorner.Visibility = Visibility.Collapsed;
ThumbTopRightCorner.Visibility = Visibility.Collapsed;
ThumbBottomLeftCorner.Visibility = Visibility.Collapsed;
ThumbBottomRightCorner.Visibility = Visibility.Collapsed;
}
else
{
ThumbBottom.Visibility = Visibility.Visible;
ThumbLeft.Visibility = Visibility.Visible;
ThumbTop.Visibility = Visibility.Visible;
ThumbRight.Visibility = Visibility.Visible;
ThumbTopLeftCorner.Visibility = Visibility.Visible;
ThumbTopRightCorner.Visibility = Visibility.Visible;
ThumbBottomLeftCorner.Visibility = Visibility.Visible;
ThumbBottomRightCorner.Visibility = Visibility.Visible;
}
}
#endregion
}
}
This can happen if ResizeBorderThickness is set to 0.
It can be set to a positive value in XAML like this:
<WindowChrome>
<WindowChrome.ResizeBorderThickness>
<Thickness>1</Thickness>
</WindowChrome.ResizeBorderThickness>
</WindowChrome>
You can use the WPF customizable window library, available here: http://wpfwindow.codeplex.com/
Then, when using the library's window type, you can set the same properties as you listed above
<CustomWindow:EssentialWindow x:Class="CustomWindowDemo.DemoEssentialWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CustomWindow="clr-namespace:CustomWindow;assembly=CustomWindow"
AllowsTransparency="True" ResizeMode="CanResize" WindowStyle="None" Title="EssentialWindow"
Height="300" Width="250">
The user needs something to interact with to resize the window. If you don't like the default border or grip, you'll need to add some other control with a click and drag behavior that resizes the window. Perhaps a line on each edge of the window?
The simplest, but maybe too simple is
this.MouseLeftButtonDown += delegate { this.DragMove(); };

Categories