Error: 'winrt::to_hstring' None of the '13' overloads could convert all the argument types - c++-winrt

i have in HeadersControl.idl below:
...
[default_interface]
runtimeclass HeadersControl : Microsoft.UI.Xaml.Controls.UserControl
{
HeadersControl();
Int32 MyProperty;
static Microsoft.UI.Xaml.DependencyProperty TitleProperty{ get; };
IInspectable Title;
...
}
...
HeadersControl.xaml
//HeadersControl.xaml
<UserControl
x:Class="TD2_WinUI3.HeadersControl"
...
mc:Ignorable="d">
<Grid>
...
<Grid x:Name="headerRoot" Padding="{Binding ElementName=headerControl, Path=Padding}" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid x:Name="pageTitle" Background="Transparent" Height="44" VerticalAlignment="Top">
<Canvas x:Name="ShadowHost" Opacity="{x:Bind ShadowOpacity, Mode=OneWay}"/>
<TextBlock x:Name="TitleTextBlock"
Style="{StaticResource TitleTextBlockStyle}"
VerticalAlignment="Center"
FontSize="{Binding ElementName=headerControl, Path=FontSize}"
Foreground="{Binding ElementName=headerControl, Path=Foreground}"
Text="{x:Bind Title, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</Grid>
</Grid>
...
</UserControl>
then in the HeadersControl.xaml.h
...
namespace winrt::TD2_WinUI3::implementation
{
struct HeadersControl : HeadersControlT<HeadersControl>
{
HeadersControl();
Windows::Foundation::IInspectable Title()
{
return GetValue(m_titleProperty);
}
void Title(Windows::Foundation::IInspectable const& value)
{
SetValue(m_titleProperty, winrt::box_value(value));
}
static Microsoft::UI::Xaml::DependencyProperty TitleProperty() { return m_titleProperty; }
...
private:
static Microsoft::UI::Xaml::DependencyProperty m_titleProperty;
...
};
}
namespace winrt::TD2_WinUI3::factory_implementation
{
struct HeadersControl : HeadersControlT<HeadersControl, implementation::HeadersControl>
{
};
}
and in HeadersControl.xaml.cpp
namespace winrt::TD2_WinUI3::implementation
{
HeadersControl::HeadersControl()
{
InitializeComponent();
...
}
Microsoft::UI::Xaml::DependencyProperty HeadersControl::m_titleProperty = Microsoft::UI::Xaml::DependencyProperty::Register
(
L"Title",
winrt::xaml_typename<Windows::Foundation::IInspectable>(),
winrt::xaml_typename<TD2_WinUI3::HeadersControl>(),
Microsoft::UI::Xaml::PropertyMetadata{ nullptr }
);
...
}
I'm getting the following errors, but as far as I can tell I've matched my dependency porperties exactly.
the complete error codes are:
Error C2665 'winrt::to_hstring': none of the 13 overloads could convert all the argument types (compiling source file Generated Files\XamlTypeInfo.g.cpp) TD2 WinUI3 C:\Users\...\source\repos\TD2 WinUI3\TD2 WinUI3\Generated Files\HeadersControl.xaml.g.hpp 211
and
Severity Code Description Project File Line Suppression State
Error C2660 'winrt::TD2_WinUI3::implementation::HeadersControlT<winrt::TD2_WinUI3::implementation::HeadersControl>::HeadersControl_obj1_Bindings::Set_Microsoft_UI_Xaml_Controls_TextBlock_Text': function does not take 1 arguments (compiling source file Generated Files\XamlTypeInfo.g.cpp) TD2 WinUI3 C:\Users\...\source\repos\TD2 WinUI3\TD2 WinUI3\Generated Files\HeadersControl.xaml.g.hpp 211

Related

How to get the parent of an object in WinUI3 with C++/WinRT?

This is how the xaml looks like:
<ListView HorizontalContentAlignment="Stretch"
x:Name="listViewMessages"
Grid.Column="1"
ItemsSource="{x:Bind MessageViewModel.Messages}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"
ItemClick="listViewMessages_ItemClick">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Message">
<Grid HorizontalAlignment="{x:Bind Path=MineToHorizontalAlignment()}" Background="{x:Bind Path=MineBackgroundColor()}" CornerRadius="8" Margin="0,6,0,2" Padding="6">
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
...
<Button Grid.Column="5" Click="Button_Click">D</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So when I will click the button I want to get the list view item of the clicked button.
How can I achieve this?
Edit:
I changed the xaml example to a more specific one.
You need to use the VisualTreeHelper Class to traverse the visual tree. Here is a C++/WinRT utility to walk the parents recursively:
template <typename T>
T GetParent(DependencyObject obj)
{
if (!obj)
return nullptr;
auto parent = Microsoft::UI::Xaml::Media::VisualTreeHelper::GetParent(obj);
if (!parent)
return nullptr;
auto parentAs = parent.try_as<T>();
if (parentAs)
return parentAs;
return GetParent<T>(parent);
}
And it's C# counterpart for what it's worth:
public static T GetParent<T>(DependencyObject obj) => (T)GetParent(obj, typeof(T));
public static object GetParent(DependencyObject obj, Type type)
{
if (obj == null)
return null;
var parent = VisualTreeHelper.GetParent(obj);
if (parent == null)
return null;
if (type.IsAssignableFrom(parent.GetType()))
return parent;
return GetParent(parent, type);
}
So you would call it like this:
void MainWindow::Button_Click(IInspectable const& sender, RoutedEventArgs const&)
{
auto listView = GetParent<Controls::ListView>(sender.try_as<DependencyObject>());
}

Hide column or row when content is not visible

I have an XAML Grid with columns and I would like to hide or collapse the column when the content is not visible.
Example:
I have this layout:
<Grid >
<Button Grid.Column="0" x:Name="FirstButton" Text="First button" />
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
When FirstButton is not visible I want this result
<Grid >
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
Answering myself :
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=IsVisible, Converter={StaticResource IsVisibleToGridLength}" BindingContext="{x:Reference FirstButton}" />
<ColumnDefinition Width="{Binding Path=IsVisible, Converter={StaticResource IsVisibleToGridLength}" BindingContext="{x:Reference SecondButton}" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="FirstButton" Text="First button" />
<Button Grid.Column="1"x:Name="SecondButton" Text="Second button" />
</Grid>
And for the converter part
class IsVisibleToGridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo language)
{
try
{
GridUnitType t = GridUnitType.Star;
if (parameter != null)
{
Enum.TryParse<GridUnitType>((string)parameter, true, out t);
}
if (value != null)
{
bool d = (bool)value;
return d == false ? new GridLength(0,GridUnitType.Absolute) : new GridLength(1, t);
}
return null;
}
catch (Exception exp)
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
{
return null;
}
}
And Obviously the App.xml part
<Application x:Class="MyNameSpace.App"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:class="clr-namespace:MyNameSpace.Class;assembly=MyNameSpace"/>
<Application.Resources>
<ResourceDictionary>
<class:IsVisibleToGridLengthConverter x:Key="IsVisibleToGridLength"/>
</ResourceDictionary>
</Application.Resources>
</Application>
Hope it helps !!

MVVM binding cutom property to view model

I am new in MVVVM so please forgive me if it is stupid question. I am using this example http://www.codeproject.com/Articles/36848/WPF-Image-Pixel-Color-Picker-Element and included there library to get color of indicated by user pixel of image. it looks nice and dipsalys in rectangle selected color but i neeed to bind the selecteed value to viewmodel.
here is my xaml code:
<Window x:Class="MovieEditor.View.PixelSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:ColorPickerControls;assembly=ColorPickerControls"
xmlns:local="clr-namespace:MovieEditor.MVVMCommon"
Title="FilterDesigner" Height="550" Width="550"
Icon="..\Resources\Images\icon.ico"
xmlns:VM="clr-namespace:MovieEditor.ViewModel">
<Window.DataContext>
<VM:PixelSelectorVM/>
</Window.DataContext>
<Window.Resources>
<local:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
</Window.Resources>
<Grid Background="#FF191919" >
<DockPanel>
<Grid Margin="10,10,10,1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" MinHeight="38"/>
</Grid.RowDefinitions>
<Border BorderBrush="White" BorderThickness="5" Margin="0,39,0,11">
<ctrls:ImageColorPicker Binding.XmlNamespaceManager="{Binding p PixelSelectorVM.MyImageColorPicker, UpdateSourceTrigger=PropertyChanged}"
x:Name="image" Source ="{Binding Frame}" Margin="0,36,0,0"
/>
</Border>
<Border Width="77"
HorizontalAlignment="Center"
BorderBrush="White" BorderThickness="1" Margin="263,2,182,435">
<Rectangle Fill="{Binding ElementName=image, Path=SelectedColor,
Converter={StaticResource ColorToBrushConverter}}" RenderTransformOrigin="0.549,0.429" Margin="1"/>
</Border>
<Button Content="Save" Command="{Binding Save}" Margin="165,0,0,4" Grid.Row="1" HorizontalAlignment="Left" Width="60"/>
<Label Content="Selected pixel color:" HorizontalAlignment="Left" Height="18" Margin="140,11,0,0" VerticalAlignment="Top" Width="110"/>
<Button Content="Cancel" Command="{Binding Cancel}" Margin="0,1,165,4" HorizontalAlignment="Right" Width="60" RenderTransformOrigin="0.5,0.5" Grid.Row="1">
</Button>
</Grid>
</DockPanel>
</Grid>
</Window>
</code>
And here is my view model:
public class PixelSelectorVM : ViewModelBase
{
private BitmapImage frame;
public MainWindowVM parentMainWindowVM;
private ImageColorPicker imageColorPicker;
public ImageColorPicker MyImageColorPicker
{
get
{
return this.imageColorPicker;
}
set
{
this.imageColorPicker = value;
OnPropertyChanged("MyImageColorPicker");
}
}
public BitmapImage Frame
{
get
{
return this.frame;
}
set
{
this.frame = value;
OnPropertyChanged("Frame");
}
}
public PixelSelectorVM(BitmapImage image, MainWindowVM mainWindowVM)
{
this.frame = image;
this.parentMainWindowVM = mainWindowVM;
this.imageColorPicker = new ImageColorPicker();
this.imageColorPicker.Source = image;
}
public PixelSelectorVM() { }
public ICommand Save
{
get
{
return new RelayCommand(SaveExecute);
}
}
public ICommand Cancel
{
get
{
return new RelayCommand(CancelExecute);
}
}
private void SaveExecute()
{
}
private void CancelExecute()
{
}
}
Please suggest me solution how can i pass the selected color to view model
You should be able to bind ImageColorPicker's SelectedColor to ViewModel's Property.
So in XAML add the binding:
SelectedColor="{Binding MySelectedColor, Mode=TwoWay}"
And in VM add the MySelectedColor property:
private Color selectedColor;
public Color MySelectedColor
{
get
{
return this.selectedColor;
}
set
{
this.selectedColor = value;
OnPropertyChanged("MySelectedColor");
}
}
When control's SelectedColor changes, it should automatically update the MySelectedColor in your VM.

TextBox not triggering PropertyChanged event

I am struggling to figure out why a propertychanged event or lostfocus event is not being triggered when I enter text into a textbox and navigate away from the control.
I am building a Universal Windows Platform app.
I know I'm doing something retarded but I just don't see it.
Any suggestions?
XAML:
<Page
x:Class="xxx.Client.FormPage"
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:viewModels="using:xxx.xxx.ViewModels"
Background="LightBlue"
mc:Ignorable="d">
<Page.Resources>
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="TextAlignment" Value="Center" />
</Style>
</Page.Resources>
<Page.DataContext>
<viewModels:FormViewModel />
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding InstructorNameInput}" Style="{StaticResource TextBoxStyle}"
PlaceholderText="Instructor Name" />
<TextBox Grid.Row="1" Text="{Binding InstructorIdInput}" Style="{StaticResource TextBoxStyle}"
PlaceholderText="Instructor Id" />
<TextBox Grid.Row="2" Text="{Binding CourseInput}" Style="{StaticResource TextBoxStyle}"
PlaceholderText="Course" />
<Button Grid.Row="4" Content="Accept" Command="{Binding Submit}"
HorizontalAlignment="Stretch"
Foreground="Black" />
</Grid>
</Page>
ViewModel:
public partial class FormViewModel : ViewModelBase
{
public FormViewModel()
{
InstructorName = new RequiredField("Instructor's Name:");
InstructorId = new RequiredField("Instructor's Employee#:");
Course = new RequiredField("Course:");
var courses = CourseFactory.Produce();
var administration = new Administration(courses, null);
Submit = new DelegateCommand(_=> OnSubmit(), CanSubmit);
}
string _instructorNameInput = null;
public string InstructorNameInput
{
get { return _instructorNameInput; }
set
{
if (_instructorNameInput != value)
{
_instructorNameInput = value;
OnNotifyPropertyChanged();
}
}
}
string instructorIdInput = null;
public string InstructorIdInput
{
get { return instructorIdInput; }
set
{
if (instructorIdInput != value)
{
instructorIdInput = value;
OnNotifyPropertyChanged();
}
}
}
string courseInput = null;
public string CourseInput
{
get { return courseInput; }
set
{
if (courseInput != value)
{
courseInput = value;
OnNotifyPropertyChanged();
}
}
}
public RequiredField InstructorName { get; }
public RequiredField InstructorId { get; }
public RequiredField Course { get; }
public ObservableCollection<RequiredField> RequiredFields { get; } = new ObservableCollection<RequiredField>();
}
ViewModel.internal:
public partial class FormViewModel
{
static void OnSubmit()
{
var adminsistration = new Administration();
}
bool CanSubmit(object obj) => !GetUnsatisfied().Any();
IEnumerable<RequiredField> GetUnsatisfied()
{
if (string.IsNullOrEmpty(InstructorIdInput))
{
RequiredFields.Add(InstructorId);
}
else
{
var result = 0;
var isNumeric = int.TryParse(InstructorIdInput, out result);
if (!isNumeric)
{
RequiredFields.Add(new RequiredField(InstructorId.About, "Instructor ID must be numeric"));
}
}
if (string.IsNullOrEmpty(InstructorNameInput))
{
RequiredFields.Add(InstructorName);
}
if (string.IsNullOrEmpty(CourseInput))
{
RequiredFields.Add(Course);
}
return RequiredFields;
}
}
The default binding mode for UWP as MSDN says:
The default is OneWay.
Set it to TwoWay:
<TextBox Grid.Row="0" Text="{Binding InstructorNameInput, Mode=TwoWay}" .../>

Why are the datagrid delete command buttons disabled?

I have a DataGrid where each row has a delete button. If I set the Command="Delete" attribute on the Delete button element in XAML, the button is disabled at runtime. Why??
XAML:
<Page x:Class="AxureExport.TargetPage"
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:AxureExport"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
Title="Define Export Targets"
Loaded="Page_Loaded">
<Page.Resources>
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="PreviewMouseLeftButtonDown"
Handler="DataGridCell_PreviewMouseLeftButtonDown" />
</Style>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7" />
<ColumnDefinition Width="65" />
<ColumnDefinition Width="458*" />
<ColumnDefinition Width="47" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="7" />
<RowDefinition Height="63*" />
</Grid.RowDefinitions>
<!-- target file -->
<TextBlock Name="textBlock3"
Text="2. Select the location where you want to save the string files:"
Height="23"
HorizontalAlignment="Left"
Margin="5,0,0,0"
VerticalAlignment="Top"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="4"
Width="441" />
<TextBlock Name="textBlock4"
Text="(Warning: This tool overwrites files in the target folder.)"
Height="16"
HorizontalAlignment="Left"
Margin="54,15,0,0"
VerticalAlignment="Top"
Width="256"
FontStyle="Italic"
FontWeight="Light"
FontSize="10"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2" />
<TextBlock Name="textBlock5"
Text="Target:"
Height="23"
HorizontalAlignment="Left"
Margin="22,30,0,238"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="1" />
<!-- ExportTargets Datagrid -->
<DataGrid Name="ExportTargets"
AutoGenerateColumns="False"
Grid.Column="2"
Grid.Row="1"
Margin="0,71,0,63"
ItemsSource="{Binding Path=., Mode=TwoWay}"
SelectionUnit="Cell"
GridLinesVisibility="None"
RowDetailsVisibilityMode="Collapsed"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
RowHeaderWidth="40"
IsSynchronizedWithCurrentItem="True"
HorizontalScrollBarVisibility="Disabled"
CanUserAddRows="True"
CanUserDeleteRows="True">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}"
Color="Black" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding IsXML, Mode=TwoWay}"
Header="XML"
CanUserSort="False"
CanUserReorder="False" />
<DataGridCheckBoxColumn Binding="{Binding IsProperty, Mode=TwoWay}"
Header="Property"
CanUserSort="False"
CanUserReorder="False" />
<DataGridTextColumn Binding="{Binding FolderName, Mode=TwoWay}"
Header="Folder"
Width="*"
CanUserReorder="False"
IsReadOnly="False" />
<DataGridTemplateColumn Header="Browse">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="Browse"
Command="{Binding BrowseCommand}"
HorizontalAlignment="Center"
Width="20">...</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="Delete"
Command="{x:Static DataGrid.DeleteCommand}"
HorizontalAlignment="Center"
Width="20"
IsEnabled="True">X</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Name="NextButton"
Content="Next"
Grid.Column="2"
Grid.ColumnSpan="2"
Grid.Row="1"
Margin="0,0,2,12"
Width="100"
Height="40"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="NextButton_Click" />
</Grid>
</Page>
Code-behind:
// DataTable
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace AxureExport {
/// <summary>
/// Interaction logic for TargetPage.xaml
/// </summary>
public partial class TargetPage : Page {
FrameWindow _frame;
//ExportTargetInfos _eti;
public TargetPage(FrameWindow frame) {
InitializeComponent();
_frame = frame;
_frame.ExportTargets = new ExportTargetInfos(Properties.Settings.Default.ExportTargetHistory);
this.DataContext = _frame.ExportTargets;
}
//
// enable editing on single-click
private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
DataGridCell cell = sender as DataGridCell;
if (!cell.IsEditing) {
if (!cell.IsFocused)
cell.Focus();
if (!cell.IsSelected)
cell.IsSelected = true;
}
}
private void Page_Loaded(object sender, RoutedEventArgs e) {
}
private void NextButton_Click(object sender, RoutedEventArgs e) {
Properties.Settings.Default.ExportTargetHistory = _frame.ExportTargets.GetExportTargets();
_frame.NavigateTo(typeof(ExportPage));
}
}
}
ViewModel:
using System;
using System.Collections.ObjectModel; // ObservibleCollection<>
using System.Collections.Specialized; // StringCollection
using System.ComponentModel; // INotifyPropertyChanged
namespace AxureExport {
public class ExportTargetInfos : ObservableCollection<ExportTargetInfo> {
const char _SEP = '|'; // field seperator character
// default constructor
public ExportTargetInfos() : base() {
}
// copy constructors
public ExportTargetInfos(ExportTargetInfos etis) : base() {
if (etis == null) return;
foreach (ExportTargetInfo eti in etis) {
this.Add(new ExportTargetInfo(eti.FolderName, eti.IsXML, eti.IsProperty));
}
}
public ExportTargetInfos(StringCollection sc) : base() {
if (sc == null) return;
foreach (string s in sc)
Add(ParseExportTarget(s));
}
public StringCollection GetExportTargets() {
StringCollection sc = new StringCollection();
foreach (ExportTargetInfo et in this)
sc.Add(BuildExportTarget(et));
return sc;
}
// create a string from an ExportTarget (for persistance)
private static string BuildExportTarget(ExportTargetInfo et) {
return et.FolderName + _SEP + et.IsXML.ToString() + _SEP + et.IsProperty.ToString();
}
// create an ExportTarget from an unparsed string (for persistance)
private static ExportTargetInfo ParseExportTarget(string s) {
int count = s.Split(_SEP).Length - 1;
string[] items = s.Split(new[] { _SEP }, StringSplitOptions.None);
string name = (count < 1 ? String.Empty : items[0]);
bool isXML = (count > 0 ? Convert.ToBoolean(items[1]) : false);
bool isProp = (count > 1 ? Convert.ToBoolean(items[2]) : false);
return new ExportTargetInfo(name, isXML, isProp);
}
}
//
// represents an export target (folder plus options) in it's parsed form
public class ExportTargetInfo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public IDelegateCommand BrowseCommand { protected set; get; }
// default constructor is needed to enable datagrid to add rows
public ExportTargetInfo() {
_folderName = String.Empty;
_isXML = false;
_isProperty = false;
this.BrowseCommand = new DelegateCommand(ExecuteBrowse, CanExecuteBrowse);
}
public ExportTargetInfo(string targetFolderName, bool isXML, bool isProperties) {
_folderName = targetFolderName;
_isXML = isXML;
_isProperty = isProperties;
this.BrowseCommand = new DelegateCommand(ExecuteBrowse, CanExecuteBrowse);
}
private string _folderName;
public string FolderName {
get { return _folderName; }
set { SetProperty<string>(ref _folderName, value, #"FolderName"); }
}
private bool _isXML;
public bool IsXML {
get { return _isXML; }
set { SetProperty<bool>(ref _isXML, value, #"IsXML"); }
}
private bool _isProperty;
public bool IsProperty {
get { return _isProperty; }
set { SetProperty<bool>(ref _isProperty, value, #"IsProperty"); }
}
// browse button for selected row clicked
void ExecuteBrowse(object param) {
// use WPF-WinForms interop (:-p)
var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
folderDialog.Description = "Please designate the target folder";
folderDialog.SelectedPath = FolderName;
folderDialog.ShowNewFolderButton = true;
if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
FolderName = folderDialog.SelectedPath;
}
bool CanExecuteBrowse(object param) {
return true;
}
protected bool SetProperty<T>(ref T storage, T value, string propertyName = null) {
if (object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName) {
if (PropertyChanged != null)
PropertyChanged( this, new PropertyChangedEventArgs(propertyName));
}
}
}
Does anyone have insight as to what's the cause?
This isn't a solution, but through trial & error I discovered the disabled delete button behavior is caused by the SelectionUnit="Cell" setting in the DataGrid. Setting it to FullRow enables the delete row button.
<Button Name="NextButton" isEnable = "true" />