Spa*_*rky 1 c# data-binding wpf xaml
我一直在寻找一种方法,将数字存储为对象的属性,并将其位模式显示为 Windows Presentation Foundation 中的一系列复选框。这是我现在使用的方法,当选中复选框时数值更新,当数字更改时复选框更新。请告诉我是否可以通过更简单的方式实现这一点。
MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Media;
using System.Windows;
using System.Windows.Controls;
namespace WPF_Interface_Tests
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public BitField BF { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
BF = new BitField(0, 32);
}
private void Plus_Click(object sender, RoutedEventArgs e)
{
if (BF.Value < uint.MaxValue)
BF.Value += 1;
}
private void Minus_Click(object sender, RoutedEventArgs e)
{
if (BF.Value > uint.MinValue)
BF.Value -= 1;
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
SystemSounds.Beep.Play();
var a = (CheckBox)sender;
int checkity = 0;
if (a.IsChecked.Value)
checkity = 1;
BF.Value = BF.Value | (uint)(checkity << (int)a.Tag);
}
}
public class Bit : INotifyPropertyChanged
{
private bool state;
public bool State { get { return state; } set { if (this.state != value) { this.state = value; NotifyPropertyChanged("State"); } } }
public int Index { get; set; }
public Bit()
{
State = false;
Index = 0;
}
public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
}
public class BitField : INotifyPropertyChanged
{
private uint value;
public uint Value { get { return value; } set { if (this.value != value) { this.value = value; NotifyPropertyChanged("Value"); UpdateValues(); } } }
public byte ByteSize { get; set; }
public ObservableCollection<Bit> Values { get; set; }
public BitField(uint givenValue, byte givenByteSize)
{
Value = givenValue;
ByteSize = givenByteSize;
Values = new ObservableCollection<Bit>();
for (int i = 0; i < ByteSize; i++)
{
if ((Value | (uint)(1 << i)) == Value)
Values.Add(new Bit { State = true, Index = i });
else
Values.Add(new Bit { State = false, Index = i });
}
}
private void UpdateValues()
{
for (int i = 0; i < Values.Count; i++)
{
if ((Value | (uint)(1 << i)) == Value)
Values[i].State = true;
else
Values[i].State = false;
}
}
public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
}
}
Run Code Online (Sandbox Code Playgroud)
主窗口.xaml
<Window x:Class="WPF_Interface_Tests.MainWindow"
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:WPF_Interface_Tests"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,201,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=BF.Value, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="Minus" Content="-" HorizontalAlignment="Left" Margin="10,229,0,0" VerticalAlignment="Top" Width="20" Click="Minus_Click" />
<ListBox x:Name="LBofChecks" HorizontalAlignment="Left" Height="186" Margin="10,10,0,0" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Path=BF.Values, UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=State, Mode=TwoWay}" Tag="{Binding Path=Index}" Click="CheckBox_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="Plus" Content="+" HorizontalAlignment="Left" Margin="35,229,0,0" VerticalAlignment="Top" Width="20" Click="Plus_Click" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
我的方法涉及使用一个新颖的BitField对象作为主窗口的属性。我设置DataContext = this并构建该BitField属性。
BitField当其Value属性发生变化时发出通知。该Value属性存储表示位序列的数字。对于用作绑定到复选框的属性的值列表,我给出了BitField一个ObservableCollection<Bit> Values属性。对象集合Bit还让每个对象在其Statebool 属性更改时发出通知。我还将对象所在的Bit每个存储在 中。您可以看到,在.xaml 文件的模板中,我将复选框的属性与其 .xaml 文件的相关联。IndexBitObservableCollection<Bit> ValuesCheckBoxTagIndexBit
也许有更简单的方法吗?
小智 5
在 ViewModel 方面,我只公开一个用于绑定的整数/字节属性 - 例如,int 表示 32 位值。将其称为“MyValue”以供讨论。是的,改变时仍然通知。
在视图方面,我可以通过两种方式将每个复选框的“IsChecked”属性绑定到 MyValue。对于“位”绑定,您将使用转换器,例如将其称为BinaryValueToBitConverter。
转换器采用 int (或字节等)并将其转换为每个复选框的 true false。关键是对于每个复选框,您都使用复选框的位位置作为ConverterParameter转换器的 Convert() 方法:
return (value & (1 << bitParam)) != 0;
Run Code Online (Sandbox Code Playgroud)
其中“bitParam”是传递的ConverterParameter(当然)。
您可能会找到一种方法来使用 CheckBox 的父控件的子索引,例如 StackPanel/ListBox 作为 ConverterParameter。
希望有帮助
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |