Binds MewUI controls to data using ObservableValue and ValueBinding. Use when implementing reactive UI updates, building ViewModels, or connecting controls to data sources.
Reactive value container:
// Create
var name = new ObservableValue<string>("Initial");
var count = new ObservableValue<int>(0);
var enabled = new ObservableValue<bool>(true);
// Read/Write
string current = name.Value;
name.Value = "New"; // Triggers Changed event
// Subscribe via Changed event
name.Changed += () => Console.WriteLine($"Changed to: {name.Value}");
// With coercion (value constraint)
var percent = new ObservableValue<double>(50, coerce: v => Math.Clamp(v, 0, 100));
percent.Value = 150; // Becomes 100
var vm = new MyViewModel();
new StackPanel().Children(
// One-way (source → UI)
new Label().BindText(vm.Message),
// Two-way (source ↔ UI)
new TextBox().BindText(vm.Name),
new CheckBox().BindIsChecked(vm.IsEnabled),
new Slider().BindValue(vm.Volume),
// With converter
new Label().BindText(vm.Count, c => $"Count: {c}"),
// Common bindings
new Button().BindIsEnabled(vm.CanSubmit).BindIsVisible(vm.ShowButton)
)
public class PersonViewModel
{
public ObservableValue<string> FirstName { get; } = new("");
public ObservableValue<string> LastName { get; } = new("");
public ObservableValue<string> FullName { get; } = new("");
public ObservableValue<bool> IsValid { get; } = new(false);
public PersonViewModel()
{
FirstName.Changed += Update;
LastName.Changed += Update;
}
private void Update()
{
FullName.Value = $"{FirstName.Value} {LastName.Value}".Trim();
IsValid.Value = FirstName.Value.Length > 0 && LastName.Value.Length > 0;
}
}
// Note: subscribe/unsubscribe use lambda pattern, not method group
var binding = new ValueBinding<string>(
get: () => source.Value,
set: v => source.Value = v, // null for one-way
subscribe: h => source.Changed += h,
unsubscribe: h => source.Changed -= h,
onSourceChanged: () => control.Text = source.Value
);
private bool _suppressBindingSet;
public string Text
{
get => _text;
set {
if (_text != value) {
_text = value;
if (!_suppressBindingSet) _binding?.Set(value);
InvalidateMeasure();
}
}
}
private void SetTextFromSource(string value)
{
_suppressBindingSet = true;
try { Text = value; }
finally { _suppressBindingSet = false; }
}
Advanced patterns: See viewmodel-patterns.md
npx skills add christian289/binding-mewui-data下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer