viewmodelはビュー固有の動作をきれいに保つ必要があります。 viewmodelだけで、関連するすべての設定のためのインタフェースを提供する必要があり、それは(BaseViewModel
がINotifyPropertyChanged
などを実装するために、いくつかのヘルパーメソッドが含まれます)、次のようになります:あなたが見たよう
public class TeaConfigurationViewModel : BaseViewModel
{
public TeaConfigurationViewModel()
{
_TeaNames = new string[]
{
"Lipton",
"Generic",
"Misc",
};
}
private IEnumerable<string> _TeaNames;
public IEnumerable<string> TeaNames
{
get { return _TeaNames; }
}
private string _SelectedTea;
public string SelectedTea
{
get { return _SelectedTea; }
set { SetProperty(ref _SelectedTea, value); }
}
private bool _IsHotTea;
public bool IsHotTea
{
get { return _IsHotTea; }
set { SetProperty(ref _IsHotTea, value); }
}
private bool _WithMilk;
public bool WithMilk
{
get { return _WithMilk; }
set { SetProperty(ref _WithMilk, value); }
}
private bool _WithLemon;
public bool WithLemon
{
get { return _WithLemon; }
set { SetProperty(ref _WithLemon, value); }
}
private bool _WithSyrup;
public bool WithSyrup
{
get { return _WithSyrup; }
set { SetProperty(ref _WithSyrup, value); }
}
}
、それぞれのプロパティがありますビューモデルは気にしませんどのようにプロパティが割り当てられています。
これでUIを構築できます。次の例では、一般的に、xmlns:local
がプロジェクトの名前空間を指しているとします。
私はあなたの目的のためにカスタマイズされたToggleButton
を利用勧め:
public class MyToggleButton : ToggleButton
{
static MyToggleButton()
{
MyToggleButton.DefaultStyleKeyProperty.OverrideMetadata(typeof(MyToggleButton), new FrameworkPropertyMetadata(typeof(MyToggleButton)));
}
public Brush ToggledBackground
{
get { return (Brush)GetValue(ToggledBackgroundProperty); }
set { SetValue(ToggledBackgroundProperty, value); }
}
// Using a DependencyProperty as the backing store for ToggledBackground. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ToggledBackgroundProperty =
DependencyProperty.Register("ToggledBackground", typeof(Brush), typeof(MyToggleButton), new FrameworkPropertyMetadata());
}
そしてThemes/Generic.xaml
中を:今
<Style TargetType="{x:Type local:MyToggleButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyToggleButton}">
<Border x:Name="border1" BorderBrush="Gray" BorderThickness="1" Background="{TemplateBinding Background}" Padding="5">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="border1" Property="Background" Value="{Binding ToggledBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
、このトグルボタンを使用して実際のウィンドウのコンテンツを構築します。これは、ラベルや説明もなしのみの機能コントロールを含む、ご希望のUIだけのラフスケッチです:Hot
とCold
間のボタン内容を変更する
<Grid x:Name="grid1">
<StackPanel>
<StackPanel Orientation="Horizontal">
<ComboBox
x:Name="cb1"
VerticalAlignment="Center"
IsEditable="True"
Margin="20"
MinWidth="200"
ItemsSource="{Binding TeaNames}"
SelectedItem="{Binding SelectedTea}">
</ComboBox>
<local:MyToggleButton
x:Name="hotToggle"
IsChecked="{Binding IsHotTea}"
VerticalAlignment="Center"
Margin="20" MinWidth="60"
Background="AliceBlue" ToggledBackground="Orange">
<local:MyToggleButton.Style>
<Style TargetType="{x:Type local:MyToggleButton}">
<Setter Property="Content" Value="Cold"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="Hot"/>
</Trigger>
</Style.Triggers>
</Style>
</local:MyToggleButton.Style>
</local:MyToggleButton>
</StackPanel>
<StackPanel Orientation="Horizontal">
<local:MyToggleButton
x:Name="milkToggle"
Content="Milk"
IsChecked="{Binding WithMilk}"
VerticalAlignment="Center"
Margin="20" MinWidth="60"
Background="WhiteSmoke" ToggledBackground="LightGreen"/>
<local:MyToggleButton
x:Name="lemonToggle"
Content="Lemon"
IsChecked="{Binding WithLemon}"
VerticalAlignment="Center"
Margin="20" MinWidth="60"
Background="WhiteSmoke" ToggledBackground="LightGreen"/>
<local:MyToggleButton
x:Name="syrupToggle"
Content="Syrup"
IsChecked="{Binding WithSyrup}"
VerticalAlignment="Center"
Margin="20" MinWidth="60"
Background="WhiteSmoke" ToggledBackground="LightGreen"/>
</StackPanel>
</StackPanel>
</Grid>
お知らせスタイルのトリガー。
は、(例えば、ウィンドウコンストラクタで)どこかのDataContextを初期化し
public MainWindow()
{
InitializeComponent();
grid1.DataContext = new TeaConfigurationViewModel();
}
この時点で、あなたは完全に機能するUIを持って、それがデフォルトのマウスとキーボードの入力方法で動作しますが、それは」勝ちましたまだあなたのショートカットキーをサポートしていません。
したがって、既に動作しているUIを破壊することなくキーボードショートカットを追加できます。
<Window.CommandBindings>
<CommandBinding Command="local:AutomationCommands.OpenList" Executed="OpenList_Executed"/>
<CommandBinding Command="local:AutomationCommands.ToggleHot" Executed="ToggleHot_Executed"/>
<CommandBinding Command="local:AutomationCommands.ToggleMilk" Executed="ToggleMilk_Executed"/>
<CommandBinding Command="local:AutomationCommands.ToggleLemon" Executed="ToggleLemon_Executed"/>
<CommandBinding Command="local:AutomationCommands.ToggleSyrup" Executed="ToggleSyrup_Executed"/>
</Window.CommandBindings>
をし、各ショートカットでの適切なハンドラメソッドを実装します。
public static class AutomationCommands
{
public static RoutedCommand OpenList = new RoutedCommand("OpenList", typeof(AutomationCommands), new InputGestureCollection()
{
new KeyGesture(Key.B, ModifierKeys.Control)
});
public static RoutedCommand ToggleHot = new RoutedCommand("ToggleHot", typeof(AutomationCommands), new InputGestureCollection()
{
new KeyGesture(Key.T, ModifierKeys.Control)
});
public static RoutedCommand ToggleMilk = new RoutedCommand("ToggleMilk", typeof(AutomationCommands), new InputGestureCollection()
{
new KeyGesture(Key.M, ModifierKeys.Control)
});
public static RoutedCommand ToggleLemon = new RoutedCommand("ToggleLemon", typeof(AutomationCommands), new InputGestureCollection()
{
new KeyGesture(Key.L, ModifierKeys.Control)
});
public static RoutedCommand ToggleSyrup = new RoutedCommand("ToggleSyrup", typeof(AutomationCommands), new InputGestureCollection()
{
new KeyGesture(Key.S, ModifierKeys.Control)
});
}
あなたは、あなたのメインウィンドウで、適切なアクションにそれらのコマンドをバインドすることができます。一つのアプローチは、いくつかのカスタムコマンドを作成して使用することであり、後ろの窓コード:再び
private void OpenList_Executed(object sender, ExecutedRoutedEventArgs e)
{
FocusManager.SetFocusedElement(cb1, cb1);
cb1.IsDropDownOpen = true;
}
private void ToggleHot_Executed(object sender, ExecutedRoutedEventArgs e)
{
hotToggle.IsChecked = !hotToggle.IsChecked;
}
private void ToggleMilk_Executed(object sender, ExecutedRoutedEventArgs e)
{
milkToggle.IsChecked = !milkToggle.IsChecked;
}
private void ToggleLemon_Executed(object sender, ExecutedRoutedEventArgs e)
{
lemonToggle.IsChecked = !lemonToggle.IsChecked;
}
private void ToggleSyrup_Executed(object sender, ExecutedRoutedEventArgs e)
{
syrupToggle.IsChecked = !syrupToggle.IsChecked;
}
は、それが表示さpropertを変更するだけで別の方法で、純粋にUI関連している事を結合この全体の入力を覚えていますユーザーがマウスでボタンをクリックした場合と同じバインドで変更がビューモデルに転送されます。そのようなものをビューモデルに持ち込む理由はありません。
代わりにToggleButtonを使用してみませんか? IsToggledプロパティをデータにバインドし、必要に応じて再生できます。 – CKII
'Background'などのボタンのプロパティを' Tea'クラスのプロパティにバインドすることができます。次に、コンバーターを使用して、プロパティの値に応じて背景色を設定します。 –
通常、あなたのシナリオでは 'ToggleButton'を使うことをお勧めします。次に、 'IsChecked'プロパティを利用してMVVMを使用することができます。 – grek40