C# Item命令无法编辑列表中的其他项
我有一个侧边栏(在C#WPF程序中),应该显示4个“不同”的按钮(它们实际上是两种不同的样式,它们都有另一种用于活动状态的样式)。侧栏由ItemsControl组成。我现在已经创建了一个列表,其中基于枚举值使用了正确的样式(如下所示)。这里有一个小问题:我可以这样做吗,或者我应该重写它,如果是这样的话,这样的东西是如何构建的?关键词或者我必须看的东西对我来说已经足够了 我现在真正的问题是:我已经为每个按钮绑定了一个命令,一开始并不复杂。该命令现在将其自身状态设置为NormalActive以进行测试。此列表中的第一项应该从LiveActive设置为Live(以便您始终可以看到您所知道的当前选定项)。问题是:按钮可以设置自己的状态,所以当我点击按钮3时,按钮3的状态从正常设置为正常激活。但没有发生的是从第一个按钮从LiveActive更改为Active。即使我在更改之前和之后将当前状态输出到控制台,它也会同时返回LiveActive。我还尝试将整个事件调用到dispatcher中,如果出于某种原因我不在UI线程中,它就不起作用。因此,按钮可以设置自己的状态,但不能设置其他状态。但我没有收到任何错误信息或任何东西。同时调用属性的setter方法,它只是不改变它。原因可能是什么 PluginListControl:C# Item命令无法编辑列表中的其他项,c#,wpf,xaml,sidebar,C#,Wpf,Xaml,Sidebar,我有一个侧边栏(在C#WPF程序中),应该显示4个“不同”的按钮(它们实际上是两种不同的样式,它们都有另一种用于活动状态的样式)。侧栏由ItemsControl组成。我现在已经创建了一个列表,其中基于枚举值使用了正确的样式(如下所示)。这里有一个小问题:我可以这样做吗,或者我应该重写它,如果是这样的话,这样的东西是如何构建的?关键词或者我必须看的东西对我来说已经足够了 我现在真正的问题是:我已经为每个按钮绑定了一个命令,一开始并不复杂。该命令现在将其自身状态设置为NormalActive以进行测
<Grid DataContext="{x:Static local:PluginListDesignModel.Instance}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:PluginListItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<UserControl.Resources>
<DataTemplate x:Key="PluginTile" DataType="{x:Type local:PluginListItemViewModel}">
<Button Style="{StaticResource PluginTile}" Content="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorType=ContentControl}}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
<DataTemplate x:Key="PluginActiveTile" DataType="{x:Type local:PluginListItemViewModel}">
<Button Style="{StaticResource PluginActiveTile}" Content="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorType=ContentControl}}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
<DataTemplate x:Key="PluginLiveTile" DataType="{x:Type local:PluginListItemViewModel}">
<Button Style="{StaticResource PluginLiveTile}" Content="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorType=ContentControl}}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
<DataTemplate x:Key="PluginActiveLiveTile" DataType="{x:Type local:PluginListItemViewModel}">
<Button Style="{StaticResource PluginActiveLiveTile}" Content="{Binding DataContext.Name, RelativeSource={RelativeSource AncestorType=ContentControl}}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
</UserControl.Resources>
<ContentControl d:DataContext="{x:Static local:PluginListItemDesignModel.Instance}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource PluginTile}" />
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="0">
<Setter Property="ContentTemplate" Value="{StaticResource PluginTile}" />
</DataTrigger>
<DataTrigger Binding="{Binding State}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource PluginActiveTile}" />
</DataTrigger>
<DataTrigger Binding="{Binding State}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource PluginLiveTile}" />
</DataTrigger>
<DataTrigger Binding="{Binding State}" Value="3">
<Setter Property="ContentTemplate" Value="{StaticResource PluginActiveLiveTile}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
如果现在按下底部按钮,它应该变为绿色,顶部按钮应该变为红色。
ListViewModel。实例每次调用时都会返回一个新的ListViewModel
类实例。它应该返回相同的实例:
public static ListViewModel Instance { get; } = new ListViewModel();
如何调试setter?它是从代码以外的其他地方调用的吗?我添加了一个私有变量。如下所示:private-plugintelestates-mState;public-plugintelestates-State{get=>mState;set{Console.WriteLine($”设置为:{value}”);mState=value;}我当然把它设置为State=PluginTileStates.Live;那么你怎么知道它没有设置为PluginTileStates.Live
?或者你的意思是你在UI中看不到变化?你能提供一个吗?好的,一方面样式应该改变,因为值改变了(至少从理论上讲,这是我第一次这么做,可能是因为数据模板的缘故我错过了一些东西).另一方面,如上所述,我有当前状态的输出给我,无论是在更改为PluginTileStates之前还是之后。Live。至于MCVE:我当然可以做一个小项目,但我如何将它放在这里?只需将它上传到某个地方并将链接发布到这里?所以我无法将其缩小。现在我将它作为Ste添加到问题中哦,我的上帝,这是一个致命的,同时也是一个简单的错误…这就是谜题的答案,非常感谢!
<Grid DataContext="{x:Static local:ListViewModel.Instance}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ListItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<UserControl.Resources>
<Style x:Key="Tile" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
<Style x:Key="ActiveTile" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
</Style>
<DataTemplate x:Key="PluginTile" DataType="{x:Type local:ListItemViewModel}">
<Button Width="100" Height="60" Style="{StaticResource Tile}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
<DataTemplate x:Key="PluginActiveTile" DataType="{x:Type local:ListItemViewModel}">
<Button Width="100" Height="60" Style="{StaticResource ActiveTile}" Command="{Binding DataContext.SetStateCommand, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
</DataTemplate>
</UserControl.Resources>
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource PluginTile}" />
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="0">
<Setter Property="ContentTemplate" Value="{StaticResource PluginTile}" />
</DataTrigger>
<DataTrigger Binding="{Binding State}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource PluginActiveTile}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
public void OnPropertyChanged(string name)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public enum TileStates
{
Normal = 0,
Active = 1
}
public class ListItemViewModel : BaseViewModel
{
public TileStates State { get; set; }
public ICommand SetStateCommand { get; set; }
public ListItemViewModel()
{
SetStateCommand = new RelayCommand(() =>
{
ListViewModel.Instance.Items[0].State = TileStates.Normal;
State = TileStates.Active;
});
}
}
public class ListViewModel : BaseViewModel
{
public static ListViewModel Instance => new ListViewModel();
public List<ListItemViewModel> Items { get; set; } = new List<ListItemViewModel>
{
new ListItemViewModel
{
State = TileStates.Active
},
new ListItemViewModel
{
State = TileStates.Normal
}
};
}
public class RelayCommand : ICommand
{
private Action mAction;
public event EventHandler CanExecuteChanged = (sender, e) => { };
public RelayCommand(Action action)
{
mAction = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
mAction();
}
}
public static ListViewModel Instance { get; } = new ListViewModel();