Eu tenho um UserControl que é usado como "modelo" para caixas de diálogo de janela. Ele contém um botão Fechar e um botão Cancelar.
<UserControl x:Class="TombLib.WPF.Controls.WindowControlButtons"
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:TombLib.WPF.Controls"
mc:Ignorable="d"
xmlns:darkUI="clr-namespace:DarkUI.WPF;assembly=DarkUI.WPF"
xmlns:vm="clr-namespace:TombLib.WPF.ViewModels"
xmlns:sg="clr-namespace:SpacedGridControl;assembly=SpacedGridControl"
d:DesignHeight="100" d:DesignWidth="300"
x:Name="root">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Height="Auto" Orientation="Horizontal">
<Button Name="oKButton" Margin="{x:Static darkUI:Defaults.MediumThickness}" Width="100" Height="Auto" Command="{Binding Close}" CommandParameter="{Binding Window}" Content="OK"></Button>
<Button Name="cancelButton" Margin="{x:Static darkUI:Defaults.MediumThickness}" Width="100" Height="Auto" Command="{Binding Path=Cancel}" CommandParameter="{Binding Window}" Content="Cancel"></Button>
</StackPanel>
</UserControl>
public partial class WindowControlButtons : UserControl
{
public static readonly DependencyProperty CancelProperty =
DependencyProperty.Register(
nameof(Cancel),
typeof(ICommand),
typeof(WindowControlButtons),
new PropertyMetadata(null));
public ICommand Cancel
{
get { return (ICommand)GetValue(CancelProperty); }
set { SetValue(CancelProperty, value); }
}
public static readonly DependencyProperty CloseProperty =
DependencyProperty.Register(
nameof(Close),
typeof(ICommand),
typeof(WindowControlButtons),
new PropertyMetadata(null));
public ICommand Close
{
get { return (ICommand)GetValue(CloseProperty); }
set { SetValue(CloseProperty, value); }
}
public static readonly DependencyProperty WindowParameter =
DependencyProperty.Register(
nameof(Window),
typeof(object),
typeof(WindowControlButtons),
new PropertyMetadata(null));
public object? Window
{
get { return GetValue(WindowParameter); }
set { SetValue(WindowParameter, value); }
}
public WindowControlButtons()
{
InitializeComponent();
}
}
Quero usá-lo na seguinte janela:
<Window x:Class="TombLib.WPF.Windows.SelectIdWindow"
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:TombLib.WPF.Windows"
mc:Ignorable="d"
xmlns:ctrl="clr-namespace:TombLib.WPF.Controls"
xmlns:vm="clr-namespace:TombLib.WPF.ViewModels"
xmlns:sg="clr-namespace:SpacedGridControl;assembly=SpacedGridControl"
xmlns:darkUI="clr-namespace:DarkUI.WPF;assembly=DarkUI.WPF"
Title="SelectIdWindow" Height="100" Width="300"
d:DataContext="{d:DesignInstance Type=vm:SelectIdViewModel }"
x:Name="Self">
<sg:SpacedGrid Margin="{x:Static darkUI:Defaults.MediumThickness}">
<!-- REDACTED -->
<ctrl:WindowControlButtons DataContext="{Binding ElementName=Self}" Window="{Binding ElementName=Self, Mode=OneWay}" Close="{Binding CloseCommand,Mode=OneWay}" Cancel="{Binding CancelCommand,Mode=OneWay}" Height="Auto" Width="Auto" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Right"/>
</sg:SpacedGrid>
</Window>
public partial class SelectIdWindow : Window
{
public ICommand? CloseCommand { get; set; }
public ICommand? CancelCommand { get; set; }
public SelectIdWindow()
{
CloseCommand = new WindowCloseCommand();
InitializeComponent();
}
}
public class SelectIdViewModel
{
public string RequestedId { get; set; } = string.Empty;
public IEnumerable<string> TakenIds { get; set;}
public SelectIdViewModel(IEnumerable<string> takenIDs) {
TakenIds = takenIDs;
}
}
Porém, quando abro a janela da seguinte maneira:
SelectIdWindow w = new SelectIdWindow();
var takenIDs = Entities.Select(kv => kv.Key.Name);
w.DataContext = new SelectIdViewModel(takenIDs);
w.ShowDialog();
Recebo os seguintes erros durante a vinculação de WindowControlButtons
:
É DataContext
explicitamente definido Self
como deve representar a janela, não o ViewModel. O que estou fazendo de errado aqui?
Erros de ligação mostram que o problema está nas propriedades Button.ICommand:
para corrigi-lo, adicione
ElementName=root
ligações WindowControlButtons para vincular às propriedades de dependência declaradas e não ao DataContext: