C# 如何使用绑定到模板外部方法的命令?
所以我在单选按钮上有一个命令,它绑定到itemsource(这是一个ObservableCollection)之外的方法。这产生了一个错误 单击单选按钮时 错误:C# 如何使用绑定到模板外部方法的命令?,c#,xaml,C#,Xaml,所以我在单选按钮上有一个命令,它绑定到itemsource(这是一个ObservableCollection)之外的方法。这产生了一个错误 单击单选按钮时 错误: System.Windows.Data Error: 40 : BindingExpression path error: 'TaskSelectedCommand' property not found on 'object' ''Task' (HashCode=46555789)'. BindingExpression:Path=
System.Windows.Data Error: 40 : BindingExpression path error: 'TaskSelectedCommand' property not found on 'object' ''Task' (HashCode=46555789)'. BindingExpression:Path=TaskSelectedCommand; DataItem='Task' (HashCode=46555789); target element is 'RadioButton' (Name=''); target property is 'Command' (type 'ICommand')
<Window.Resources>
<DataTemplate x:Key="Tasks">
<StackPanel>
<Grid>
<RadioButton ToolTip="Start tracker" GroupName="rdoExchange" Grid.Row="1" Grid.Column="1" Margin="2,0,10,1" Command="{Binding TaskSelectedCommand}" IsChecked="{Binding Selected}" Height="22" VerticalAlignment="Bottom"/>
<TextBox ToolTip="Task currently being tracked" IsEnabled="true" Margin="25,15,-375,4" Grid.Row="0" Grid.Column="0" Text="{Binding Name}" RenderTransformOrigin="6.033,0.727" />
<TextBox Grid.Row="0" Margin="430,15,-455,4" Grid.Column="0" Text="{Binding Time}"/>
</Grid>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel Name="allTaskList" Orientation="Vertical" Margin="0,10,0,0">
<ListBox IsSynchronizedWithCurrentItem="True" Height="171" HorizontalAlignment="Left" ItemsSource="{Binding TaskList}"
HorizontalContentAlignment="Stretch" Margin="25,10,-523,0" VerticalAlignment="Top" Width="512" ItemTemplate="{StaticResource Tasks}"/>
</StackPanel>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace Sundial
{
public class Task
{
public int id { get; set; }
public string Name { get; set; }
public double Time { get; set; }
public bool Selected { get; set; }
}
}
public ICommand TaskSelectedCommand
{
get
{
return mTaskSelected;
}
set
{
mTaskSelected = value;
}
}
public MainWindowViewModel()
{
TaskSelectedCommand = new RelayCommand(new Action<object>(TaskSelected));
TaskList = new ObservableCollection<Task>();
}
public void TaskSelected(object obj)
{
var task = TaskList.FirstOrDefault(i => i.Selected == true);
if (task != null)
{
timer.Start();
}
}
public void AddTask(object obj)
{
TaskList.Add(new Task() { id = taskNum, Name = "Task", Selected = false, Time = 0.0 });
}
数据模板XAML代码:
System.Windows.Data Error: 40 : BindingExpression path error: 'TaskSelectedCommand' property not found on 'object' ''Task' (HashCode=46555789)'. BindingExpression:Path=TaskSelectedCommand; DataItem='Task' (HashCode=46555789); target element is 'RadioButton' (Name=''); target property is 'Command' (type 'ICommand')
<Window.Resources>
<DataTemplate x:Key="Tasks">
<StackPanel>
<Grid>
<RadioButton ToolTip="Start tracker" GroupName="rdoExchange" Grid.Row="1" Grid.Column="1" Margin="2,0,10,1" Command="{Binding TaskSelectedCommand}" IsChecked="{Binding Selected}" Height="22" VerticalAlignment="Bottom"/>
<TextBox ToolTip="Task currently being tracked" IsEnabled="true" Margin="25,15,-375,4" Grid.Row="0" Grid.Column="0" Text="{Binding Name}" RenderTransformOrigin="6.033,0.727" />
<TextBox Grid.Row="0" Margin="430,15,-455,4" Grid.Column="0" Text="{Binding Time}"/>
</Grid>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel Name="allTaskList" Orientation="Vertical" Margin="0,10,0,0">
<ListBox IsSynchronizedWithCurrentItem="True" Height="171" HorizontalAlignment="Left" ItemsSource="{Binding TaskList}"
HorizontalContentAlignment="Stretch" Margin="25,10,-523,0" VerticalAlignment="Top" Width="512" ItemTemplate="{StaticResource Tasks}"/>
</StackPanel>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace Sundial
{
public class Task
{
public int id { get; set; }
public string Name { get; set; }
public double Time { get; set; }
public bool Selected { get; set; }
}
}
public ICommand TaskSelectedCommand
{
get
{
return mTaskSelected;
}
set
{
mTaskSelected = value;
}
}
public MainWindowViewModel()
{
TaskSelectedCommand = new RelayCommand(new Action<object>(TaskSelected));
TaskList = new ObservableCollection<Task>();
}
public void TaskSelected(object obj)
{
var task = TaskList.FirstOrDefault(i => i.Selected == true);
if (task != null)
{
timer.Start();
}
}
public void AddTask(object obj)
{
TaskList.Add(new Task() { id = taskNum, Name = "Task", Selected = false, Time = 0.0 });
}
MainWindowViewModel.cs代码:
System.Windows.Data Error: 40 : BindingExpression path error: 'TaskSelectedCommand' property not found on 'object' ''Task' (HashCode=46555789)'. BindingExpression:Path=TaskSelectedCommand; DataItem='Task' (HashCode=46555789); target element is 'RadioButton' (Name=''); target property is 'Command' (type 'ICommand')
<Window.Resources>
<DataTemplate x:Key="Tasks">
<StackPanel>
<Grid>
<RadioButton ToolTip="Start tracker" GroupName="rdoExchange" Grid.Row="1" Grid.Column="1" Margin="2,0,10,1" Command="{Binding TaskSelectedCommand}" IsChecked="{Binding Selected}" Height="22" VerticalAlignment="Bottom"/>
<TextBox ToolTip="Task currently being tracked" IsEnabled="true" Margin="25,15,-375,4" Grid.Row="0" Grid.Column="0" Text="{Binding Name}" RenderTransformOrigin="6.033,0.727" />
<TextBox Grid.Row="0" Margin="430,15,-455,4" Grid.Column="0" Text="{Binding Time}"/>
</Grid>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel Name="allTaskList" Orientation="Vertical" Margin="0,10,0,0">
<ListBox IsSynchronizedWithCurrentItem="True" Height="171" HorizontalAlignment="Left" ItemsSource="{Binding TaskList}"
HorizontalContentAlignment="Stretch" Margin="25,10,-523,0" VerticalAlignment="Top" Width="512" ItemTemplate="{StaticResource Tasks}"/>
</StackPanel>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace Sundial
{
public class Task
{
public int id { get; set; }
public string Name { get; set; }
public double Time { get; set; }
public bool Selected { get; set; }
}
}
public ICommand TaskSelectedCommand
{
get
{
return mTaskSelected;
}
set
{
mTaskSelected = value;
}
}
public MainWindowViewModel()
{
TaskSelectedCommand = new RelayCommand(new Action<object>(TaskSelected));
TaskList = new ObservableCollection<Task>();
}
public void TaskSelected(object obj)
{
var task = TaskList.FirstOrDefault(i => i.Selected == true);
if (task != null)
{
timer.Start();
}
}
public void AddTask(object obj)
{
TaskList.Add(new Task() { id = taskNum, Name = "Task", Selected = false, Time = 0.0 });
}
public ICommand task selected命令
{
得到
{
返回所选项目;
}
设置
{
mTaskSelected=值;
}
}
公共主窗口视图模型()
{
TaskSelectedCommand=newrelaycommand(新操作(TaskSelected));
TaskList=新的ObservableCollection();
}
已选择公共对象(对象对象对象)
{
var task=TaskList.FirstOrDefault(i=>i.Selected==true);
如果(任务!=null)
{
timer.Start();
}
}
公共无效添加任务(对象obj)
{
添加(新任务(){id=taskNum,Name=“Task”,Selected=false,Time=0.0});
}
这不是全部代码,这只是与问题相关的代码。在类似的场景中,在命令的绑定声明中使用相对资源。看看这个答案:
在编写XAML时,WPF正在视觉树中查找一个对象,从
列表框开始,该对象具有非空的DataContext
属性。当找到该对象时,它将列表框
的项资源
属性绑定到该对象名为任务列表
的属性。我假设这个绑定正在工作,因为您没有提到有任何关于绑定失败的错误消息
由于TaskList
绑定到ListBox的ItemsSource
属性,因此我假设它是一个集合
WPF接下来在TaskList
集合中的所有对象上循环,并为每个对象创建DataTemplate
的副本,将其粘贴到ListBoxItem
对象中,并将其添加到ListBox的Items
集合中。当它构建数据模板的副本时,它会尝试将单选按钮绑定到任务列表
集合中当前对象的TaskSelectedCommand
属性。它没有在该对象上找到TaskSelectedCommand
属性,因此它失败并生成错误消息
您可以在集合中的项目上创建一个TaskSelectedCommand
属性,也可以在具有TaskList
集合属性的对象上创建一个属性。在第一种情况下,您不需要更改XAML。在第二种情况下,您必须更改TaskSelectedCommand
的绑定,因此它指定了一个RelativeSource
知道为什么会这样吗?