【やろうとしていること】
画面のItemsControlのItemSourceにObservableCollection 〈Person〉を指定しています。
画面に追加ボタンとクリアボタンの2つのボタンを配置しています。
初期表示ではObservableCollectionは空で、
追加を押すとPersonクラスの名前とIDを画面表示し、クリアボタンを押すと全消しします。
中身が空の状態ではクリアボタンを非活性としたいです。
【困っていること】
クリアボタンのIsEnabledプロパティをバインドしています。
今のやり方は、追加ボタンクリック時のCommandで上記IsEnAbledをtrueにする、クリックボタンクリック時のCommandでfalseに倒すというやり方を取っています。
ObservableCollectionの中身が空かどうかで判断出来ればスマートだと思うのですが、良いやり方はありますでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
スタイルを使った方法です。
XML
1<Button Content="クリア"> 2 <Button.Style> 3 <Style TargetType="Button"> 4 <Setter Property="IsEnabled" Value="True"/> 5 <Style.Triggers> 6 <DataTrigger Binding="{Binding Persons}" Value="{x:Null}"> 7 <Setter Property="IsEnabled" Value="False"/> 8 </DataTrigger> 9 <DataTrigger Binding="{Binding Persons.Count}" Value="0"> 10 <Setter Property="IsEnabled" Value="False"/> 11 </DataTrigger> 12 </Style.Triggers> 13 </Style> 14 </Button.Style> 15</Button>
投稿2018/12/15 08:48
編集2018/12/17 01:53総合スコア4152
0
ベストアンサー
CanExecute を実装したコマンドをバインドしてください。
#追記
次のコードでは、起動時に People に要素が一つ入っているのでクリアボタンが有効です。それを押すと People がクリアされてボタンが無効になります。
MainWindow.xaml
XML
1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Window.DataContext> 10 <local:ViewModel/> 11 </Window.DataContext> 12 <Grid> 13 <Button Command="{Binding ClearCommand}">Clear</Button> 14 </Grid> 15</Window>
ViewModel.cs
C#
1using Reactive.Bindings; 2using System.Collections.ObjectModel; 3using System.Collections.Specialized; 4using System.ComponentModel; 5using System.Linq; 6using System.Reactive.Linq; 7using System.Runtime.CompilerServices; 8 9namespace WpfApp1 10{ 11 public class ViewModel : INotifyPropertyChanged 12 { 13 public event PropertyChangedEventHandler PropertyChanged; 14 protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) 15 { 16 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 17 } 18 19 public ObservableCollection<string> People { get; } = new ObservableCollection<string>(); 20 21 public ReactiveCommand ClearCommand { get; private set; } 22 23 public ViewModel() 24 { 25 ClearCommand = Observable 26 .FromEventPattern<NotifyCollectionChangedEventArgs>(People, nameof(People.CollectionChanged)) 27 .Select(_ => People.Count > 0) 28 .ToReactiveCommand(false); 29 ClearCommand.Subscribe(People.Clear); 30 People.Add("who"); 31 } 32 } 33}
投稿2018/12/15 08:43
編集2018/12/15 15:02総合スコア28673
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
ItemsControlが空かどうかでボタンの活性非活性を制御したい
Button.IsEnabled
にItemsControl.HasItems
をバインドするのが簡単です。
ItemsControl.HasItems Property (System.Windows.Controls) | Microsoft Learn
xml
1<Window 2 x:Class="Q164167.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 ThemeMode="System"> 8 <DockPanel> 9 <UniformGrid DockPanel.Dock="Bottom" Rows="1"> 10 <Button HorizontalAlignment="Stretch" Click="AddButton_Click" Content="Add" /> 11 <Button 12 HorizontalAlignment="Stretch" 13 Click="ClearButton_Click" 14 Content="Clear" 15 IsEnabled="{Binding HasItems, ElementName=itemsControl}" /> 16 </UniformGrid> 17 <ItemsControl x:Name="itemsControl" ItemsSource="{Binding People}" /> 18 </DockPanel> 19</Window>
cs
1using System.Collections.ObjectModel; 2using System.IO; 3using System.Windows; 4 5namespace Q164167; 6 7public partial class MainWindow : Window 8{ 9 public ObservableCollection<Person> People { get; } = []; 10 11 public MainWindow() 12 { 13 InitializeComponent(); 14 DataContext = this; 15 } 16 17 private void AddButton_Click(object sender, RoutedEventArgs e) 18 => People.Add(new($"{People.Count + 1}", Path.GetRandomFileName()[..8])); 19 private void ClearButton_Click(object sender, RoutedEventArgs e) => People.Clear(); 20} 21 22public record Person(string Id, string Name);
Countというint型の変更通知をどうやって受ければいいのだろうと思っていた
ObservableCollection
はINotifyPropertyChanged
も実装しますが、明示的な実装なのでキャストする必要があります。
cs
1((INotifyPropertyChanged)People).PropertyChanged += (s, e) => { };
投稿2024/11/24 15:05
総合スコア10013
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/15 15:29
2018/12/16 02:31
2018/12/17 01:54