OxyPlot PlotController - c#

I am trying to disable auto panning on right button.
using OxyPlot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OxyPlot.Wpf;
using PlotController.Properties;
namespace PlotController
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public class Chart
{
private OxyPlot.Series.LineSeries LS;
public PlotModel PlotModel {get;set;}
public Chart()
{
Random rnd = new Random();
PlotModel = new PlotModel();
LS = new OxyPlot.Series.LineSeries();
for (int i=0;i<100;i++)
{
LS.Points.Add(new DataPoint(i, rnd.Next(1,10)));
}
PlotModel.Series.Add(LS);
}
}
public partial class MainWindow : Window
{
Chart TChart;
public MainWindow()
{
TChart = new Chart();
OxyPlot.PlotController MyControl = new OxyPlot.PlotController();
MyControl.UnbindAll();
TestView = new PlotView();
TestView.Model = TChart.PlotModel;
TestView.Controller=MyControl;
DataContext = TChart;
InitializeComponent();
}
}
}
And xaml
* *
<Window x:Class="PlotController.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
Title="MainWindow" Height="350" Width="525">
<Grid>
<oxy:PlotView Name="TestView" Model="{Binding PlotModel}" DefaultTrackerTemplate="{x:Null}" ></oxy:PlotView>
</Grid>
After unbinding all PlotCommand it still working.Why? How possible to disable panning on right button and enable on left button?

Try this in your MainWindow initialization code:
TestView.ActualController.UnbindAll();
TestView is the name of your PlotView defined in XAML.

Related

Datagrid stays Empty but ObservableCollection has values

Currently i am trying to learn WPF, but i have hit a brickwall with my current Problem, after many hours googling and trying to fix it on my own. I am trying to display the Model Province. I have found multiple similar Problems but i couldn't figure it out on my own. After having checked the Output there was no mention of any error. Currently the Window shows just the empty Model but no data even though the Observable Collection gets updated. So before i completely destroy my interest in WPF i am asking for help.
MyView
<Window x:Class="isnuaatest.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:isnuaatest"
xmlns:local1="clr-namespace:isnuaatest.Models"
xmlns:local2="clr-namespace:isnuaatest.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local2:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid>
<DataGrid ItemsSource="{Binding Provinces, UpdateSourceTrigger=PropertyChanged}">
</DataGrid>
</Grid>
<StackPanel Width="200" Margin="50">
<Button x:Name="OpenSaveFile" Click="OpenSaveFile_Click">OpenSaveFile</Button>
</StackPanel>
</Grid>
My View Model
using isnuaatest.Helper;
using isnuaatest.Models;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
namespace isnuaatest.ViewModel
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public ObservableCollection<Province> _province;
public ObservableCollection<Province> Provinces
{
get { return this._province; }
set
{
_province = value;
}
}
public MainWindowViewModel() : base()
{
this.Provinces = new ObservableCollection<Province>();
}
private string _savegamePath;
public string SavegamePath
{
get { return _savegamePath; }
set { _savegamePath = value; OnPropertyChanged("SavegamePath"); GetProvinces(_savegamePath);}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var savegamefile = this.PropertyChanged;
if (savegamefile != null)
savegamefile(this, new PropertyChangedEventArgs(propertyName));
}
public event EventHandler OnItemChanged;
public void GetProvinces(string path)
{
Reader reader = new Reader();
if (_savegamePath != null)
{
FileStream fs = File.OpenRead(path);
List<Province> listofProvinces = reader.ReadTextString(fs);
foreach (Province province in listofProvinces)
{
Provinces.Add(new Province()
{
Aristocrats = province.Aristocrats,
Artisans = province.Artisans
});
}
}
}
}
}
Code Behind
using isnuaatest.Helper;
using isnuaatest.Models;
using isnuaatest.ViewModel;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace isnuaatest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindowViewModel _vm = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
private void OpenSaveFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = false;
dynamic result = fileDialog.ShowDialog();
if (result == true)
{
_vm.SavegamePath = fileDialog.FileName;
}
}
}
}
My thinking is that maybe the Data Context wont update, because the data is in the Observable Collection. If this is true how can i update the Data Context, i already tried adding it in xaml to no avail.
Thanks
You actually create 3 different MainWindowViewModel objects - one in xaml and two in code behind. You can get rid of one in xaml, once in MainWindow constructor you set DataContext xaml-one is overridden.
But two objects in code-behind cause your problem - you load file into _vm object, but it's not the one that is held in DataContext.
To fix your problem use _vm for DataContext and not the new object:
public MainWindowViewModel _vm = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _vm;
}
Change your Provinces:
public ObservableCollection<Province> Provinces
{
get { return this._province; }
set
{
_province = value;
OnPropertyChanged("Provinces");
}
}

Binding on Dependency Property of UserControl

I'm trying to create UserControls to be able to reuse them later in the WPF application. I choose to build a small project to train myself, but I can't make it work.
The objective is to have a TextBox whose content will be sent as a Label Text with the click on a Button.
I've read and tried the solutions on those links :
XAML Binding on Dependency Property
Custom Dependency Properties
Simple Dependency Property and UserControl issues in C#
Add dependency property to control
But even the starting text I set in the constructor doesn't show up, and the button click does nothing at all.
Here are my files :
MyControl.xaml
<UserControl x:Class="WpfApplication1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Name="control"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Text="{Binding TextBoxContent,ElementName=control}"/>
<Button Content="Print Entry" Grid.Row="1" Command="{Binding ButtonCommmand,ElementName=control}"/>
<Label Grid.Row="2" Content="{Binding LabelContent,ElementName=control}"/>
</Grid>
</UserControl>
MyControl.xaml.cs
using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
ButtonCommmand = new RelayCommand(Action);
}
public string TextBoxContent
{
get
{
return (string)GetValue(TextBoxContentProperty);
}
set
{
SetValue(TextBoxContentProperty, value);
}
}
public RelayCommand ButtonCommmand
{
get
{
return (RelayCommand)GetValue(ButtonCommandProperty);
}
set
{
SetValue(ButtonCommandProperty, value);
}
}
public string LabelContent {
get
{
return (string)GetValue(LabelContentProperty);
}
set
{
SetValue(LabelContentProperty, value);
}
}
public void Action()
{
LabelContent = TextBoxContent;
}
public static readonly DependencyProperty TextBoxContentProperty = DependencyProperty.Register("TextBoxContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));
public static readonly DependencyProperty ButtonCommandProperty = DependencyProperty.Register("ButtonCommmand", typeof(RelayCommand), typeof(MyControl), new PropertyMetadata(null));
public static readonly DependencyProperty LabelContentProperty = DependencyProperty.Register("LabelContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));
}
}
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"
xmlns:control="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<control:MyControl DataContext="{Binding customControl}" TextBoxContent="{Binding Text,Mode=TwoWay}" LabelContent="{Binding EndText,Mode=TwoWay}" ButtonCommmand="{Binding Command,Mode=TwoWay}"/>
</Grid>
</Window>
MainWindow.xaml.cs
using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
MyControl customControl = new MyControl();
public MainWindow()
{
InitializeComponent();
Command = new RelayCommand(Action);
Text = "Testing... Testing... 1, 2, 3,...";
}
private string text;
public string Text
{
get
{
return text;
}
set
{
text = value;
NotifyPropertyChanged();
}
}
private string endText;
public string EndText
{
get
{
return endText;
}
set
{
endText = value;
NotifyPropertyChanged();
}
}
private RelayCommand command;
public RelayCommand Command
{
get
{
return command;
}
set
{
command = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void Action()
{
EndText = Text;
}
private void NotifyPropertyChanged([CallerMemberName]string PropertyName = "")
{
if (!String.IsNullOrEmpty(PropertyName))
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
}
}
}
Thank you a lot for your help !
You are creating another instance of your UserControl in the code-behind of the window:
MyControl customControl = new MyControl();
What you want to do is to bind the properties of the UserControl that you have defined in your XAML to the properties of the window. For this to work you should set the DataContext of the window to itself:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Command = new RelayCommand(Action);
Text = "Testing... Testing... 1, 2, 3,...";
}
}
...and remove this from your XAML:
DataContext="{Binding customControl}"

Editable combobox overwrites my context menu - Fails

I have been trying to use the code in the reply to Question
"Editable combobox overwrites my context menu" asked on asked Aug 30 '12 at 14:24
But it always errors with a nullreferenceerror on
(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(combobox, 0), 2) as TextBox).ContextMenu = combobox.ContextMenu;
In order to minimize any environment problems I have added the code as a new project
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox IsEditable="True" ContextMenuService.ShowOnDisabled="True"
Name="combobox" Loaded="combobox_Loaded">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="test"></MenuItem>
</ContextMenu>
</ComboBox.ContextMenu>
<ComboBoxItem Content="Item1"></ComboBoxItem>
<ComboBoxItem Content="Item2"></ComboBoxItem>
</ComboBox>
</Grid>
</Window>
code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void combobox_Loaded(object sender, RoutedEventArgs e)
{
(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(combobox, 0), 2) as TextBox).ContextMenu = combobox.ContextMenu;
}
}
}
This is working:
private void combobox_Loaded(object sender, RoutedEventArgs e)
{
(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(combobox, 0), 2), 0) as TextBox).ContextMenu = combobox.ContextMenu;
}
You have to go another level.
Because the TextBox is inside a border.
You can use Snoop application to inspect the xaml tree.

Using an object in code, which is instantiated in xaml

I am trying to experiment making simple GUI application.
In it I have made a simple class called consle. I am using a button click to trigger an event Button_Click_1. This should in turn call the function wrStr which changes the value of variable change internally. This changed value should reflect in the GUI because the variable change is also bound in the XAML code.
The problem is, I do not know how to access the consle type object instantiated in XAML code. If I get the name of the object instantiated in XAML I could just say <NameOfObject>.wrStr() inside the Button_Click_1 function.
The XAML code is given below:
<Window x:Class="TryBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TryBinding"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Set44" HorizontalAlignment="Left" Margin="244,37,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<TextBlock HorizontalAlignment="Left" Margin="339,76,0,0" TextWrapping="Wrap" Text="{Binding Source=consle, Path=change, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top"/>
</Grid>
The cs code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TryBinding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
}
}
public class consle
{
public string mainstr {get; set;}
public int change { get; set; }
public consle()
{
}
public void wrStr()
{
change = 44;
}
}
}

WPF - Unable to set properties of dynamically added User Control via deserialization

File des.txt --> this file is deserialized to xaml tree
<NewLabel NewText="some new text" LabelText="yes" xmlns="clr-namespace:WpfPractice;assembly=WpfPractice" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><av:Grid><av:Canvas><av:TextBox Width="100" Height="30">yes</av:TextBox></av:Canvas></av:Grid></NewLabel>
Mainwindow.xaml
<Window x:Class="WpfPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfPractice"
Title="MainWindow"
Width="525"
Height="350">
<Grid Name="theGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="1"
Width="50"
Height="25"
Click="Button_Click_2"
Content="Click" />
</Grid>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
namespace WpfPractice
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
NewLabel someNewLabel;
public MainWindow()
{
InitializeComponent();
someNewLabel = (NewLabel)DeserializeXaml(File.ReadAllText(#"D:\des.txt"));
theGrid.Children.Add(someNewLabel);
}
void Serialize()
{
NewLabel theNewLabel = new NewLabel();
theNewLabel.NewText = "some new text";
string xamlString = XamlWriter.Save(theNewLabel);
XmlReader reader = XmlReader.Create(new StringReader(xamlString));
UIElement copy = XamlReader.Load(reader) as UIElement;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
someNewLabel.LabelText = "new value";
someNewLabel.SetLabelValue("asdfsadgsafgreg");
//Serialize();
}
public object DeserializeXaml(string xaml)
{
StringReader stringReader = new StringReader(xaml);
XmlReader xmlReader = XmlReader.Create(stringReader);
return System.Windows.Markup.XamlReader.Load(xmlReader);
}
}
}
NewLabel.xaml
<UserControl x:Class="WpfPractice.NewLabel"
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"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Name="theGrid">
</Grid>
NewLabel.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfPractice
{
/// <summary>
/// Interaction logic for NewLabel.xaml
/// </summary>
public partial class NewLabel : UserControl, INotifyPropertyChanged
{
public static DependencyProperty NameProperty =
DependencyProperty.Register("NewText",
typeof(string),
typeof(NewLabel),
new PropertyMetadata(String.Empty));
public string NewText
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
private string _labelText = "yes";
public string LabelText
{
get
{
return _labelText;
}
set
{
_labelText = value;
OnPropertyChanged("LabelText");
}
}
Label theLabel;
public NewLabel()
{
InitializeComponent();
theLabel = new Label();
theLabel.Height = 30;
theLabel.Width = 100;
theLabel.Content = "old value";
Canvas theCanvas = new Canvas();
theCanvas.Children.Add(theLabel);
theGrid.Children.Add(theCanvas);
Binding b = new Binding("LabelText");
b.Source = this;
theLabel.SetBinding(TextBox.TextProperty, b);
theLabel.MouseDoubleClick += theLabel_MouseDoubleClick;
this.DataContext = this;
}
void theLabel_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("clicked!");
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
public void SetLabelValue(string val)
{
theLabel.Content = val;
}
}
}
Question:
Both these statements in MainWindow.xaml.cs
someNewLabel.LabelText = "new value";
someNewLabel.SetLabelValue("asdfsadgsafgreg");
do not work. In other words, I am unable to set the textbox property to "new value"
You are creating the binding in NewLable constructor, but then you load a new visual tree from a file which overrides the original one. That why you cant update the label nor by binding neither by setting the value directly because its not in the visual tree anymore.

Categories

Resources